一、SpringCloud Gateway 简介
SpringCloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。
SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 2.0之前的非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
Spring Cloud Gateway 的目标,不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。
二、SpringCloud Gateway 特征
SpringCloud官方,对SpringCloud Gateway 特征介绍如下:
- 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
- 集成 Hystrix 断路器
- 集成 Spring Cloud DiscoveryClient
- Predicates 和 Filters 作用于特定路由,易于编写的 Predicates 和 Filters
- 具备一些网关的高级功能:动态路由、限流、路径重写
从以上的特征来说,和Zuul的特征差别不大。SpringCloud Gateway和Zuul主要的区别,还是在底层的通信框架上。
简单说明一下上文中的三个术语:
- Filter(过滤器):
和Zuul的过滤器在概念上类似,可以使用它拦截和修改请求,并且对上游的响应,进行二次处理。过滤器为org.springframework.cloud.gateway.filter.GatewayFilter
类的实例。
- Route(路由):
网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route
模块由一个ID
,一个目标URI
,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。
- Predicate(断言):
这是一个 Java 8 的Predicate
,可以使用它来匹配来自HTTP
请求的任何内容,例如headers
或参数。断言的输入类型是一个 ServerWebExchange
。
三、Spring Cloud Gateway的处理流程
客户端向 Spring Cloud Gateway 发出请求。然后在Gateway Handler Mapping
中找到与请求相匹配的路由,将其发送到Gateway Web Handler
。Handler
再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(pre
)或之后(post
)执行业务逻辑。
四、路由匹配规则
对于这种配置类的,我们一般情况都会放到配置文件中去配置。
Spring Cloud Gateway 的功能很强大,我们仅仅通过 Predicates 的设计就可以看出来,前面我们只是使用了 predicates 进行了简单的条件匹配,其实 Spring Cloud Gataway 帮我们内置了很多 Predicates 功能。
Spring Cloud Gateway 是通过 Spring WebFlux 的 HandlerMapping 做为底层支持来匹配到转发路由,Spring Cloud Gateway 内置了很多 Predicates 工厂,这些 Predicates 工厂通过不同的 HTTP 请求参数来匹配,多个 Predicates 工厂可以组合使用。
代码Demo
父工程依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.12.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<!-- <version>2.1.0.RELEASE</version>-->
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
当前模块依赖
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
配置文件
server:
port: 9527
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: 192.168.120.180:8848
gateway:
discovery:
locator:
enabled: true
routes:
- id: payment-routh
uri: lb://nacos-provider-payment # 服务名称
predicates:
- Path=/app/**
- Header=username,laughing
可以看到gateway的路由匹配规格主要是包含id
、uri
、predicates
。id
随意指定,唯一即可。uri
代表配置的路径,可以匹配URL
或者服务名称,如果是服务名称,以lb:
打头。predicates
代表断言,条件为true
时才能进入对应的路径。
说白了 Predicate 就是为了实现一组匹配规则,方便让请求过来找到对应的 Route 进行处理,接下来我们接下 Spring Cloud GateWay 内置几种 Predicate 的使用。
假定转发uri都设定为lb://nacos-provider-payment
规则 | 实例 | 说明 |
---|---|---|
Path | - Path=/gate/,/rule/ | 当请求的路径为gate、rule开头的时,转发到nacos-provider-payment 服务 |
Before | - Before=2017-01-20T17:42:47.789-07:00[America/Denver] | 在某个时间之前的请求才会被转发到nacos-provider-payment 服务 |
After | - After=2017-01-20T17:42:47.789-07:00[America/Denver] | 在某个时间之后的请求才会被转发到nacos-provider-payment 服务 |
Between | - Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver] | 在某个时间段之间的才会被转发 |
Cookie | - Cookie=chocolate, ch.p | 名为chocolate的表单或者满足正则ch.p的表单才会被匹配到进行请求转发 |
Header | - Header=X-Request-Id, \d+ | 携带参数X-Request-Id或者满足\d+的请求头才会匹配 |
Host | - Host=www.xiangcaowuyu.net | 当主机名为www.xiangcaowuyu.net的时候直接转发到nacos-provider-payment 服务 |
Method | - Method=GET | 只有GET方法才会匹配转发请求,还可以限定POST、PUT等请求方式 |
测试我们上面代码的匹配规则
如果我们访问的路径是/echo
开头,并且Header
中username=laughing
就转发到nacos-provider-payment
服务。
第一次正常访问
第二次,我们配置Header
可以看到报404
第三次,我们配置Header
但是参数值设置为test
,可以看到也是报404
其他参数配置我们不再测试。
五、过滤器规则(Filter)
过滤规则 | 实例 | 说明 |
---|---|---|
PrefixPath | - PrefixPath=/app | 在请求路径前加上app |
RewritePath | - RewritePath=/test, /app/test | 访问localhost:9022/test,请求会转发到localhost:8001/app/test |
SetPath | SetPath=/app/{path} | 通过模板设置路径,转发的规则时会在路径前增加app,{path}表示原请求路径 |
RedirectTo | 重定向 | |
RemoveRequestHeader | 去掉某个请求头信息 |
测试Demo
我们只测试一个PrefixPath
服务提供者
@GetMapping(value = "app/echo/{string}")
public String echo1(@PathVariable("string") String string) {
return "app/echo/{string} " + string+"\t当前服务端口:"+serverPort;
}
配置文件
server:
port: 9527
spring:
application:
name: cloud-gateway-service
cloud:
nacos:
discovery:
server-addr: 192.168.120.180:8848
gateway:
discovery:
locator:
enabled: true
routes:
- id: payment-routh
uri: lb://nacos-provider-payment # 服务名称
predicates:
- Path=/**
filters:
PrefixPath=/app
评论 (0)