SpringCloud - Spring Cloud 之 Gateway网关(十三)
阅读本文前可先参考
SpringCloud - Spring Cloud根/父项目,开发准备(二)_MinggeQingchun的博客-CSDN博客
一、API网关
API网关,软件术语,两个相互独立的局域网之间通过路由器进行通信,中间的路由被称之为网关。
任何一个应用系统如果需要被其他系统调用,就需要暴露 API,这些 API 代表着一个一个的功能点。
如果两个系统中间通信,在系统之间加上一个中介者协助 API 的调用,这个中介者就是 API 网关
API 网关是一个搭建在客户端和微服务之间的服务,我们可以在 API 网关中处理一些非业务功能的逻辑,例如权限验证、监控、缓存、请求路由等。
API 网关就像整个微服务系统的门面一样,是系统对外的唯一入口。有了它,客户端会先将请求发送到 API 网关,然后由 API 网关根据请求的标识信息将请求转发到微服务实例。
对于服务数量众多、复杂度较高、规模比较大的系统来说,使用 API 网关具有以下好处:
- 客户端通过 API 网关与微服务交互时,客户端只需要知道 API 网关地址即可,而不需要维护大量的服务地址,简化了客户端的开发。
- 客户端直接与 API 网关通信,能够减少客户端与各个服务的交互次数。
- 客户端与后端的服务耦合度降低。
- 节省流量,提高性能,提升用户体验。
- API 网关还提供了安全、流控、过滤、缓存、计费以及监控等 API 管理功能。
常见的 API 网关实现方案主要有以下 5 种:
- Spring Cloud Gateway
- Spring Cloud Netflix Zuul
- Kong
- Nginx+Lua
- Traefik
二、Gateway
Spring Cloud Gateway 是 Spring Cloud 团队基于 Spring 5.0、Spring Boot 2.0 和 Project Reactor 等技术开发的高性能 API 网关组件。
Spring Cloud Gateway 是基于 WebFlux 框架实现的,而 WebFlux 框架底层则使用了高性能的 Reactor 模式通信框架 Netty
Spring Cloud GateWay 最主要的功能就是路由转发,而在定义转发规则时主要涉及了以下三个核心概念
1、Route(路由)
2、Predicate(断言)
3、Filter(过滤)
核心概念 | 描述 |
---|---|
Route(路由) | 网关最基本的模块。它由一个 ID、一个目标 URI、一组断言(Predicate)和一组过滤器(Filter)组成。 |
Predicate(断言) | 路由转发的判断条件,我们可以通过 Predicate 对 HTTP 请求进行匹配,例如请求方式、请求路径、请求头、参数等,如果请求与断言匹配成功,则将请求转发到相应的服务。 |
Filter(过滤器) | 过滤器,我们可以使用它对请求进行拦截和修改,还可以使用它对上文的响应进行再处理。 |
注:其中 Route 和 Predicate 必须同时声明
Spring Cloud Gateway 工作流程
1、客户端将请求发送到 Spring Cloud Gateway 上
2、Spring Cloud Gateway 通过 Gateway Handler Mapping 找到与请求相匹配的路由,将其发送给 Gateway Web Handler。
3、Gateway Web Handler 通过指定的过滤器链(Filter Chain),将请求转发到实际的服务节点中,执行业务逻辑返回响应结果。
4、过滤器之间用虚线分开是因为过滤器可能会在转发请求之前(pre)或之后(post)执行业务逻辑。
5、过滤器(Filter)可以在请求被转发到服务端前,对请求进行拦截和修改,例如参数校验、权限校验、流量监控、日志输出以及协议转换等。
6、过滤器可以在响应返回客户端之前,对响应进行拦截和再处理,例如修改响应内容或响应头、日志输出、流量监控等。
7、响应原路返回给客户端
三、Gateway应用
1、新建一个springboot Module(springcloud-7-service-eureka-gateway)
2、添加 spring-cloud-starter-gateway;spring-cloud-starter-netflix-eureka-client等 依赖
注:
在 gateway 网关服务中不能引入 spring-boot-starter-web 的依赖,否则会报错
spring-cloud-starter-gateway 使用的Netty服务器,而 spring-boot-starter-web 使用 的Tomcat服务器;Spring Cloud Gateway使用是基于WebFlux和Netty开发的,和传统的Tomcat服务器方式不同
<dependencies><!--spring-cloud-starter-netflix-eureka-client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- Spring cloud gateway 网关依赖特别注意:在 gateway 网关服务中不能引入 spring-boot-starter-web 的依赖,否则会报错Spring Cloud Gateway使用是基于WebFlux和Netty开发的,和传统的Tomcat服务器方式不同--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency></dependencies>
<!--继承统一的父项目--><parent><groupId>com.company</groupId><artifactId>springcloud-demo</artifactId><version>1.0.0</version></parent><groupId>com.company</groupId><artifactId>springcloud-7-service-eureka-gateway</artifactId><version>1.0.0</version><name>springcloud-7-service-eureka-gateway</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><!--spring-cloud-starter-netflix-eureka-client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- Spring cloud gateway 网关依赖特别注意:在 gateway 网关服务中不能引入 spring-boot-starter-web 的依赖,否则会报错Spring Cloud Gateway使用是基于WebFlux和Netty开发的,和传统的Tomcat服务器方式不同--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
3、application.properties配置文件
server.port=81#eureka注册中心首页的Application这一栏
spring.application.name=springcloud-7-service-eureka-gateway#每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活”
eureka.instance.lease-renewal-interval-in-seconds=2
#告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出
eureka.instance.lease-expiration-duration-in-seconds=10
#告诉服务端,服务实例以IP作为链接,不是取机器名
eureka.instance.prefer-ip-address=false#注册服务实例ID,,服务ID必须唯一 springcloud-7-service-eureka-gateway
eureka.instance.instance-id=${spring.application.name}:${server.port}
#注册中心的链接地址 http://eureka8761:8761/eureka,http://eureka8762:8762/eureka,http://eureka8763:8763/eureka
eureka.client.service-url.defaultZone=http://localhost:8761/eureka#网关路由配置
#开启网关,默认开启
spring.cloud.gateway.enabled=true
#节点 routes 是一个List 对象,其中 routes 集合中中又包含多个对象,每个对象有三个属性(一个 索引[0]代表一个对象)
#路由 id,没有固定规则,但唯一
spring.cloud.gateway.routes[0].id=login-service-route
#匹配后提供服务的路由地址;uri统一资源定位符 url 统一资源标识符
spring.cloud.gateway.routes[0].uri=http://localhost:9001
#以下是断言条件,必选全部符合条件;断言是给某一个路由来设定的一种匹配规则 默认不能作用在动态路由上
#断言,路径匹配,只要Path匹配上了/doLogin 就往 uri 转发 并且将路径带上 注意:Path 中 P 为大写
#也可以全局匹配,如 /service/**
spring.cloud.gateway.routes[0].predicates[0]=Path=/doLogin
#只能是 GET 请求时,才能访问
spring.cloud.gateway.routes[0].predicates[0]=Method=GET
application.yml写法
server:port: 81#eureka注册中心首页的Application这一栏
spring:application:name: springcloud-7-service-eureka-gateway#网关路由配置cloud:gateway:#开启网关,默认开启enabled: true#节点 routes 是一个List 对象,其中 routes 集合中中又包含多个对象,每个对象有三个属性(一个 索引[0]代表一个对象)routes:#路由 id,没有固定规则,但唯一- id: login-service-route#匹配后提供服务的路由地址;uri统一资源定位符 url 统一资源标识符uri: http://localhost:9001#以下是断言条件,必选全部符合条件;断言是给某一个路由来设定的一种匹配规则 默认不能作用在动态路由上predicates:#断言,路径匹配,只要Path匹配上了/doLogin 就往 uri 转发 并且将路径带上 注意:Path 中 P 为大写#也可以全局匹配,如 /service/**- Path=/doLogin#只能是 GET,POST 请求时,才能访问- Method=GET,POSTeureka:instance:#每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活”lease-renewal-interval-in-seconds: 2#告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出lease-expiration-duration-in-seconds: 10#告诉服务端,服务实例以IP作为链接,不是取机器名prefer-ip-address: false#注册服务实例ID,,服务ID必须唯一 springcloud-7-service-eureka-gatewayinstance-id: ${spring.application.name}:${server.port}#注册中心的链接地址 http://eureka8761:8761/eureka,http://eureka8762:8762/eureka,http://eureka8763:8763/eurekaclient:service-url:defaultZone: http://localhost:8761/eureka
注:
(1)Gateway 网关建议 使用 yml 文件格式配置,以properties配置比较繁琐,一般公司项目也建议采取 yml格式
(2)不管 application.properties 还是 application.yml 写法,都要注意 断言 predicates 处的 Path=/doLogin 和 Method=GET,POST写法,不然报如下错误
***************************
APPLICATION FAILED TO START
***************************Description:Binding to target [Bindable@4a6facb0 type = java.util.List<org.springframework.cloud.gateway.handler.predicate.PredicateDefinition>, value = 'provided', annotations = array<Annotation>[@javax.validation.constraints.NotEmpty(message={javax.validation.constraints.NotEmpty.message}, groups=[], payload=[]), @javax.validation.Valid()]] failed:Property: spring.cloud.gateway.routes[0].predicates[0].pathValue: /doLoginOrigin: class path resource [application.yml]:23:21Reason: The elements [spring.cloud.gateway.routes[0].predicates[0].path,spring.cloud.gateway.routes[0].predicates[1].method] were left unbound.Property: spring.cloud.gateway.routes[0].predicates[1].methodValue: GET,POSTOrigin: class path resource [application.yml]:25:23Reason: The elements [spring.cloud.gateway.routes[0].predicates[0].path,spring.cloud.gateway.routes[0].predicates[1].method] were left unbound.
4、在 Spring Boot 的启动类中,添加 @EnableEurekaClient 注解开启 Eureka 客户端功能(Gateway网关也是eureka的客户端)
@EnableEurekaClient //Gateway网关也是eureka的客户端
@SpringBootApplication
public class EurekaGateway7Application {public static void main(String[] args) {SpringApplication.run(EurekaGateway7Application.class, args);}
}
5、创建一个服务提供者 springcloud-7-service-eureka-gateway-login
依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--spring-cloud-starter-netflix-eureka-client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency></dependencies>
application.properties
server.port=9001#设置应用名称,对应Eureka控制台下 DS Replicas 的 Application(集群部署服务提供者,Application一致,对应多个eureka.instance.instance-id)
spring.application.name=springcloud-7-service-eureka-gateway-login#每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活”
eureka.instance.lease-renewal-interval-in-seconds=5
#告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出
eureka.instance.lease-expiration-duration-in-seconds=10
#告诉服务端,服务实例以IP作为链接,不是取机器名
eureka.instance.prefer-ip-address=false#注册服务实例ID,,服务ID必须唯一
eureka.instance.instance-id=springcloud-7-service-eureka-gateway-login
#注册中心的链接地址 http://localhost:8761/eureka
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
controller测试类
@RestController
public class LoginController {@GetMapping("/doLogin")public String doLogin(String name, String pwd) {System.out.println(name);System.out.println(pwd);// tokenString token = UUID.randomUUID().toString();return token;}
}
6、分别启动本地 eureka,gateway,login-service ,输入访问 http://localhost:81/doLogin
注:
这里启动 Gateway网关模块,会明显的在控制台下方看到输出:
Netty started on port(s):81
服务者自己的端口 9001 访问 自然无问题
SpringCloud - Spring Cloud 之 Gateway网关(十三)相关推荐
- Spring Cloud :Gateway 网关限流(五)
目录 一.概述 1. 为什么需要限流 二.限流算法 1. 计数器算法 2. 漏桶算法 3. 令牌桶算法 四.Gateway 限流 1. 添加依赖 2. 配置文件 3. 限流规则配置类 Spring C ...
- 【Spring Cloud】 Gateway网关 之 那些好玩的网关过滤器
1.添加请求头的网关过滤 AddRequestHeader 匹配到的路由将添加指定的请求头和值 格式为 请求头名称 , 请求头值 server:port: 81 spring:cloud:gatewa ...
- Spring Cloud学习笔记—网关Spring Cloud Gateway官网教程实操练习
Spring Cloud学习笔记-网关Spring Cloud Gateway官网教程实操练习 1.Spring Cloud Gateway介绍 2.在Spring Tool Suite4或者IDEA ...
- SpringCloud - Spring Cloud Netflix 之 Zuul网关;路由(十一)
阅读本文前可先参考 SpringCloud - Spring Cloud根/父项目,开发准备(二)_MinggeQingchun的博客-CSDN博客 一.API网关 引自百度百科 API网关,软件术语 ...
- Spring Cloud(10)——新一代网关Spring Cloud Gateway
文章目录 Spring Cloud(10)--新一代网关Spring Cloud Gateway 1.背景知识--API网关 2.Spring Cloud Gateway 详细概述 3.Spring ...
- Spring Cloud(六) 服务网关GateWay 入门
前文回顾: Spring Cloud(一)Eureka Server-单体及集群搭建 Spring Cloud(二) 配置Eureka Client Spring Cloud(三) 熔断器Hystri ...
- Spring Cloud入门-Gateway服务网关(Hoxton版本)
文章目录 Spring Cloud入门系列汇总 摘要 Gateway 简介 相关概念 创建 api-gateway模块 在pom.xml中添加相关依赖 两种不同的配置路由方式 使用yml配置 使用Ja ...
- Spring Cloud Alibaba - Gateway 入门案例(二)(Gateway 整合 nacos /(非阿里组件))
Spring Cloud Alibaba - Gateway 入门案例(二)(Gateway 整合 nacos)(非阿里组件) 回溯 Gateway 整合 nacos 方式一(复杂/灵活/常用) 方式 ...
- Spring Cloud(七) GateWay 服务化和过滤器
前文回顾: Spring Cloud(一)Eureka Server-单体及集群搭建 Spring Cloud(二) 配置Eureka Client Spring Cloud(三) 熔断器Hystri ...
最新文章
- mysql 语句碎片
- 通过DLL使两个工程公用部分代码
- java登录失败重新登录_为什么我的一直都是进入登录失败界面
- 《高级软件测试》实践作业4学习记录12月25日
- 音视频技术开发——还有什么不能讲的?
- OPA 1 - testsuite.opa.html
- gitee图床不能用了,心态崩了
- FASTQ format
- poto——剧院魅影——phantom of the opera
- cad图框尺寸标准图_基于AutoCAD2020的动态图框制作与图纸比例问题
- Linux DHCP服务详解
- 华为ICT大赛省赛网络赛道
- linux vscode设置终端字体(要求等宽字体)
- java输出罗马数字_java工具类——罗马数字和阿拉伯数字相互转换
- linux ubuntu 18.04无法输入中文、安装中文拼音输入法
- 滴滴校招编程题-田径运动会比赛排名
- ps2021中文版完美逆袭
- 云管平台监控实践分享
- 高德地图API行政区域查询
- 显卡Memory Clock上限问题排查实践