spring-cloud(十一)GateWay强大的路由谓词(断言)功能
GateWay强大的路由谓词(断言)功能
spring-cloud-Hoxton.SR6 (十一)GateWay强大的路由谓词(断言)功能
本文spring-cloud 版本为:hoxton.sr6
本文spring-boot版本为:2.2.x-2.3.x
路由谓词:Spring Cloud Gateway将路由匹配作为Spring WebFluxHandlerMapping
基础架构的一部分。Spring Cloud Gateway包括许多内置的路由谓词工厂。所有这些谓词都与HTTP请求的不同属性匹配。您可以将多个路由谓词工厂与逻辑and
语句结合使用。
说人话就是:请求匹配机制(触发路由条件)即符合Predicate的条件,就使用该路由的配置,否则对请求不做任何处理
例如我们前方配置的:
spring:
cloud:
gateway:
routes:
#最普通的路由
- id: easy-order
uri: http://localhost:9002/
predicates:
- Path=/order/**
-Path=/order/**
即是我们前边配置的一种路由谓词,这个配置的意思呢即是当我们的请求url路径中包含了/order/** 则会将请求转发到 http://localhost:9002/
-Path 方式的谓词呢,被称为路径路线谓词工厂
…
接下来呢,咱们进行系统的梳理梳理gateway所支持的路由谓词工厂
(1)路径-谓词工厂
路径谓词,即当请求(请求url包含某路径时触发路由),例如前边讲的 - Path=/product/**
,则要求请求url中包含/product/** 时触发路由
- Path=路径1
exmaple: 请求Url包含/product/**
时触发路由 ,将请求转发到 demo-product
服务中
具体配置如下:
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product
uri: lb://demo-product
predicates:
- Path=/product/**
需要注意的是Path是可以配置多个的,例如这样:
- Path=路径1,路径2,路径3.....
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product
uri: lb://demo-product
predicates:
- Path=/product/**,/zs/{a}
那么,当我们请求url中包含 /product/**
或/zs/{a}
(这里不要被{xxx}误解了,其实际与/zs/* 一致,仅仅只能匹配一级目录 即 /zs/li
、/zs/aaaa
)时都会将请求转发到 demo-peoduct服务
综上,便是路径谓词工厂的使用了,一般也是微服务使用最多的路由谓词
(2)后时刻-谓词工厂
可以设置一个时间点,当系统时间大于设置时间点时才会将请求进行路由
- After=时刻
具体配置如下:
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product
uri: lb://demo-product
predicates:
# [Asia/Shanghai] 为时间所对应的时区
- After=2020-10-13T21:57:33.993+08:00[Asia/Shanghai]
这样设置后谓词工厂后呢,即是当系统时间(上海时区)大于2020年10月13日21点57分30秒后 ,才会将请求进行路由
当请求时间小于设置的路由时间时 接口请求404 ,为何呢,因为网关并未将我们的请求转发到demo-product
服务
当系统时间大于设置的后路由时间时(即满足条件),才会将我们的请求转发到demo-product
服务。
(3)前时刻-谓词工厂
与后路径谓词工厂一样,一样是支持一个时间点设置,当当前请求时间小于设置的路由时间时,才会将请求进行路由
- Before=时刻
配置如下:
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product
uri: lb://demo-product
predicates:
# [Asia/Shanghai] 为时间所对应的时区
- Before=2020-10-13T22:12:33.993+08:00[Asia/Shanghai]
小于设定的前路由时间,可以正常访问,请求也路由到了demo-product
服务
当请求时间大于设置的前路由时间,不会触发路由
(4)时间段-谓词工厂
这个时间段路由谓词呢,实际就是 前时刻 后时刻 两个路由谓词的综合,其配置需要设置两个时间点,当请求时间在这两个时间点之间,则会触发路由,反之则不进行路由。
- Between=时刻1,时刻2
配置如下:
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product
uri: lb://demo-product
predicates:
# [Asia/Shanghai] 为时间所对应的时区
- Between=2020-10-13T22:24:33.993+08:00[Asia/Shanghai],2020-10-13T22:26:33.993+08:00[Asia/Shanghai]
从我的配置中,大家可以看到,一个时间点是2020-10-13T22:24:33.993+08:00
,一个时间点是2020-10-13T22:26:33.993+08:00
前一个时间点,是触发后时刻路由(即时间大于此时刻则进行路由)
后一个时间点,是触发前时刻路由(即时间小于此时刻则进行路由)
即请求时间在 2020-10-13-22:24:33 请求时间> 2020-10-13-22:24:33
请求时间小于设置的时间段时访问:
请求时间满足于设置的时间段时访问:
请求时间超过设置时间段时访问:
哎,这个时候呢,可能有小伙子不信这个邪,你Between 设置两个时间,你说前一个时间点满足 后时刻谓词,后一个时间点满足前时刻谓词 ,你说是就是吗?
来,实践走着!我们把前一个时间点设置大点,后一个时间点设置小一点
- Between=2020-10-13T22:32:33.993+08:00[Asia/Shanghai],2020-10-13T22:28:33.993+08:00[Asia/Shanghai]
修改后启动试一试,直接启动报错
reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalArgumentException: 2020-10-13T22:32:33.993+08:00[Asia/Shanghai] must be before 2020-10-13T22:28:33.993+08:00[Asia/Shanghai]
Caused by: java.lang.IllegalArgumentException: 2020-10-13T22:32:33.993+08:00[Asia/Shanghai] must be before 2020-10-13T22:28:33.993+08:00[Asia/Shanghai]
错误提示很明显,要求2020-10-13T22:32:33.993+08:00[Asia/Shanghai]
必需要小于2020-10-13T22:28:33.993+08:00[Asia/Shanghai]
所以呢,这个Between 设置的两个时刻呢,必须前时刻小于后时刻,即必须时刻1<时刻2
其实呢,无论是前时刻、后时刻、时间段 路由谓词,我们正式项目一般都使用很少,但其这个特性可以在某些限定时间接口开放相关业务的时候,还是能够使用到的…
(5)cookie-谓词工厂
看名字,即可猜出当前路由触发条件了,即当我们的请求包含某cookie的时候才会进行路由,
- Cookie=cookie名字,值(值支持正则表达式)
详细配置如下:
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product
uri: lb://demo-product
predicates:
- Cookie=username,lei
如果按照我这么配置,那么我们的请求必须携带userme的cookie ,且其值必须为lei
当cookie不满足时,则无法触发路由
cookie的值设置正则表达式示例
我下边呢,就设置一个cookie名为username 且值必须以字母开始(无论大小)
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product
uri: lb://demo-product
predicates:
- Cookie=username,^[A-Za-z_]
请求中携带的cookie以字母开头
请求中携带cookie的值不为字母开头
(6)方法-谓词工厂
所谓方法谓词工厂,即是根据HTTP请求类型匹配来路由,例如GET、POST、PUT、DELETE等等,可配置多种请求方法
- Method=GET,POST
详细配置如下:
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product
uri: lb://demo-product
predicates:
- Method=GET,POST
如此配置,则只有当请求为GET、POST时才会触发路由
测试:
GET
POST
当我们的Http方法类型与配置的方法谓词匹配时,才会触发路由,如果方法类型不匹配,则不会触发路由
(7)请求头-谓词工厂
请求头是什么不用多讲,我们作为开发如果连这个都不知道,那么可以好好地补补知识了…
例如我们在实际开发中,通常会设置一个token请求头,当有些接口需要登录访问,则会校验当前请求是否携带一个token
请求头…
或者说,我们前后端交互的时候,要求前端向后端传输JSON
格式的参数,那么在HTTP请求的时候,需要加上一个Content-Type= application/json
的一个键值对请求头…
我们的请求头谓词呢,即是要求当前HTTP请求必须携带定义的请求头才会触发路由
例如如下配置:
- Header=Authentication,leilei
详细配置
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product
uri: lb://demo-product
predicates:
- Header=Authentication,leilei
那么如此配置呢,则必须要求我们的请求携带一个Authentication
的请求头键 ,且值为leilei
才会进行路由
测试查看
当我们的请求携带设置的请求头时
需要注意的是,我们的请求头的值也是支持正则表达式的,例如
- Header=Authentication,\d+
如此设置呢,则要求我们的请求必须含有Authentication
,且值必须为一个或多个纯数字
(8)权重-谓词工厂
我们做后端的,都应该知道这个词:负载均衡
而在负载均衡中呢,又涉及到了负载的权重策略 ,例如随机
、轮询
、权重
等
何为权重?权重,说白了就是某一因素对某一事物的重要程度,程度的高低则为权重的高低
例如:你很花心,同时呢,有两个很好的女伴,A、B都很喜欢约你出去玩,一年下来你算了一下,平均你与A一起玩耍4次,才会和B玩耍一次…
那么,就说明,你更喜欢和A在一起玩,(可能是A更有钱嘛,也可能是你单纯的馋…),但是你心里是有数的,在A、B两者中,A在你选择游玩的伙伴分量是大于B的,那么此时就是你出行游玩伙伴选择A的权重则是大于B的…
在服务器的选择中呢,可能也是涉及到权重问题
我们的gateway呢,在路由谓词的时候即支持权重了,可根据我们配置的权重比,将请求进行相应量化的转发
其需要设置两个参数一个是group
一个是weight
即权重分组和权重比
- Weight=组, 权重比
详细配置
spring:
cloud:
gateway:
routes:
# 9001 服务设置为testWeight分组,比重设置4
- id: server-product2
uri: http://localhost:9001/
predicates:
- Weight=testWeight, 4
# 9000 服务设置为testWeight分组,比重设置1
- id: server-product2
uri: http://localhost:9000/
predicates:
- Weight=testWeight, 1
那么,访问的时候,同一个请求在9001处理四次后,第五次才会交由9000服务进行处理
…这个不是很好演示,截图篇幅太长了…只有自己手动测试了哈…
(9)查询参数-谓词工厂
即当我们的请求中含有某个请求参数时,才会进行路由
此设置则只要求请求参数中必须携带参数名为:【参数名】
- Query=【参数名】
此设置则要求请求参数必须携带参数名为:【参数名】 且值为【值】
- Query=【参数名】,【值】(支持正则)
详细配置
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product
uri: lb://demo-product
predicates:
- Query=name
无设置的参数请求
有gateway路由谓词设置的参数请求
设置固定参数名,且值设为正则匹配
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product
uri: lb://demo-product
predicates:
- Query=name,A.
那么此设置呢,则要求请求中必须携带参数名为name
,且值必须以A开头
(10)主机-谓词工厂
即需要我们的请求头中必须要携带设置的主机信息,才会对我们的请求进行路由
主机名列表可设置多个,例如下边这样
- Host=主机1,主机2,主机3......
详细配置
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product2
uri: lb://demo-product
predicates:
- Host=**.zsls.org,**.wermazi.org
**
则支持模糊匹配
**.zsls.org
则我们的请求头携带HOST=zs.zsls.org
可以 aaa.zsls.org
也可以**.
部分可作为模糊
测试:
按照谓词设置,传入正确格式主机名:
(11)RemoteAddr/网段-路由谓词工厂
当前谓词呢,即只接受设置的某一网段类的请求,当请求来自于某一网段时,才会触发路由
示例:
- RemoteAddr=192.168.1.1/24
详细配置
spring:
cloud:
gateway:
routes:
#服务名路由 负载均衡
- id: server-product2
uri: lb://demo-product
predicates:
- RemoteAddr=192.168.124.1/24
即当请求方的IP为192.168.124.1
-192.168.124.24
之间时,才会触发路由
..............................................
..............................................
..............................................
那么以上呢,便是我们gateway所支持的所有路由谓词了!各位可下载我的源码进行自校验哦!
附上官网链接:gateway
附上项目源码:spring-cloud-hoxton-sr6
下一篇:GateWay强大的Filter功能…敬请期待
更多推荐
所有评论(0)