简介:
Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。
优势:
Spring Cloud Gateway 可以看做是一个 Zuul 1.x 的升级版和代替品,比 Zuul 2 更早的使用 Netty 实现异步 IO,从而实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。
Spring Cloud Gateway 里明确的区分了 Router 和 Filter,并且一个很大的特点是内置了非常多的开箱即用功能,并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。
比如内置了 10 种 Router,使得我们可以直接配置一下就可以随心所欲的根据 Header、或者 Path、或者 Host、或者 Query 来做路由。
比如区分了一般的 Filter 和全局 Filter,内置了 20 种 Filter 和 9 种全局 Filter,也都可以直接用。当然自定义 Filter 也非常方便。
三大核心概念:
- Route: The basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates断言, and a collection of filters. A route is matched if the aggregate predicate is true.发一个请求给网关,网关要将请求路由到指定的服务。路由有id,目的地uri,断言的集合,匹配了断言就能到达指定位置,如果断言为真,则路由匹配
- Predicate断言: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This lets you match on anything from the HTTP request, such as headers or parameters.就是java里的断言函数,匹配请求里的任何信息,包括请求头等。根据请求头路由哪个服务
- Filter: These are instances of Spring Framework GatewayFilter that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request.过滤器请求和响应都可以被修改,Filter分为两种类型的Filter,分别是Gateway Filter和Global Filter.
客户端发请求给服务端。中间有网关。先交给映射器,如果能处理就交给handler处理,然后交给一系列filer,然后给指定的服务,再返回回来给客户端。
使用
1,pom.xml中加上gateway的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2,开启注册服务发现@EnableDiscoveryClient
@EnableDiscoveryClient
@SpringBootApplication
public class GulimallGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GulimallGatewayApplication.class, args);
}
}
3,配置nacos注册中心地址applicaion.properties
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.application.name=gulimall-gateway
server.port=88
4, bootstrap.properties 填写nacos配置中心地址
spring.application.name=gulimall-gateway
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=bfa85f10-1a9a-460c-a7dc-efa961b45cc1
5,项目里创建application.yml,根据条件转发到uri
spring:
cloud:
gateway:
routes:
- id: test_route
uri: https://www.baidu.com
predicates:
- Query=url,baidu
- id: qq_route
uri: https://www.qq.com
predicates:
- Query=url,qq
- id: product_route
uri: lb://gulimall-product
predicates:
- Path=/api/product/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{segment}
6,测试 localhost:8080/hello?url=baidu
Predicate(断言)的使用
通过时间匹配
Predicate 支持设置一个时间,在请求进行转发的时候,可以通过判断在这个时间之前或者之后进行转发。
After Route Predicate:
在这个时间之后的请求都转发到目标地址
spring:
cloud:
gateway:
routes:
- id: time_route
uri: http://ityouknow.com
predicates:
- After=2020-01-20T06:06:06+08:00[Asia/Shanghai]
上面的示例是指,请求时间在 2020 年 1 月 20 日 6 点 6 分 6 秒之后的所有请求都转发到地址http://ityouknow.com。+08:00是指时间和 UTC 时间相差八个小时,时间地区为Asia/Shanghai。
添加完路由规则之后,访问地址http://localhost:8080会自动转发到http://ityouknow.com
Before Route Predicate:
在某个时间之前的请求的请求都进行转发
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://ityouknow.com
predicates:
- Before=2021-02-02T06:06:06+08:00[Asia/Shanghai]
这个表示在2021年2月2日6 点 6 分 6 秒之前所有请求都转发到地址http://ityouknow.com,在这个时间之后就会停止路由,修改完后再次访问的话,会报404
Between Route Predicate
限制路由请求在某一个时间段范围内
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://ityouknow.com
predicates:
- Between=2021-02-02T06:06:06+08:00[Asia/Shanghai],2021-03-02T06:06:06+08:00[Asia/Shanghai]
置就意味着在这个时间段内可以匹配到此路由,超过这个时间段范围则不会进行匹配。通过时间匹配路由的功能很酷,可以用在限时抢购的一些场景中
通过Cookie匹配
Cookie Route Predicate
可以接收两个参数,一个是 Cookie name , 一个是正则表达式,路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://ityouknow.com
predicates:
- Cookie=ityouknow, kee.e
Header Route Predicate
接收 2 个参数,一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://ityouknow.com
predicates:
- Header=X-Request-Id, \d+
通过Host匹配
Host Route Predicate
接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。它通过参数中的主机地址作为匹配规则。
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://ityouknow.com
predicates:
- Host=**.ityouknow.com
通过请求方式匹配
可以通过是 POST、GET、PUT、DELETE 等不同的请求方式来进行路由
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://ityouknow.com
predicates:
- Method=GET
通过请求路径匹配
Path Route Predicate
接收一个匹配路径的参数来判断是否走路由
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://ityouknow.com
predicates:
- Path=/foo/{segment}
/foo/1或者/foo/test符合请求路径要求,则路由将匹配
通过请求参数匹配
Query Route Predicate
支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式
- 只要请求中包含smile属性的参数即可匹配路由
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://ityouknow.com
predicates:
- Query=smile
- 将 Query 的值以键值对的方式进行配置,这样在请求过来时会对属性值和正则进行匹配,匹配上才会走路由
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://ityouknow.com
predicates:
- Query=keep, pu.
只要当请求中包含 keep 属性并且参数值是以 pu 开头的长度为三位的字符串才会进行匹配和路由
通过请求 ip 地址进行匹配
RemoteAddr Route Predicate
接受 cidr 符号 (IPv4 或 IPv6) 字符串的列表(最小大小为 1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)。
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: http://ityouknow.com
predicates:
- RemoteAddr=192.168.1.1/24
组合使用
spring:
cloud:
gateway:
routes:
- id: host_foo_path_headers_to_httpbin
uri: http://ityouknow.com
predicates:
- Host=**.foo.org
- Path=/headers
- Method=GET
- Header=X-Request-Id, \d+
- Query=foo, ba.
- Query=baz
- Cookie=chocolate, ch.p
- After=2018-01-
各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。
一个请求满足多个路由的断言时,请求只会被首个成功匹配的路由转发