spring-cloud(十一)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服务

image-20201012223253597

image-20201012223413881

综上,便是路径谓词工厂的使用了,一般也是微服务使用最多的路由谓词

(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服务

image-20201013215643027

当系统时间大于设置的后路由时间时(即满足条件),才会将我们的请求转发到demo-product服务。

image-20201013215923708

(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服务

image-20201013221144242

当请求时间大于设置的前路由时间,不会触发路由

image-20201013221300239

(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

请求时间小于设置的时间段时访问:

image-20201013222409414

请求时间满足于设置的时间段时访问:

image-20201013222457248

请求时间超过设置时间段时访问:

image-20201013222646812

哎,这个时候呢,可能有小伙子不信这个邪,你Between 设置两个时间,你说前一个时间点满足 后时刻谓词,后一个时间点满足前时刻谓词 ,你说是就是吗?

来,实践走着!我们把前一个时间点设置大点,后一个时间点设置小一点

- Between=2020-10-13T22:32:33.993+08:00[Asia/Shanghai],2020-10-13T22:28:33.993+08:00[Asia/Shanghai]

修改后启动试一试,直接启动报错

image-20201013223139965

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

image-20201013225812665

当cookie不满足时,则无法触发路由

image-20201013225852327

cookie的值设置正则表达式示例

细心的给您贴上正则表达式的连接

我下边呢,就设置一个cookie名为username 且值必须以字母开始(无论大小)

spring:
  cloud:
    gateway:
      routes:
        #服务名路由 负载均衡
        - id: server-product
          uri: lb://demo-product
          predicates:
            - Cookie=username,^[A-Za-z_]

请求中携带的cookie以字母开头

image-20201013231642956

请求中携带cookie的值不为字母开头

image-20201013231937434

(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

image-20201014215056551

POST

image-20201014215250363

当我们的Http方法类型与配置的方法谓词匹配时,才会触发路由,如果方法类型不匹配,则不会触发路由

image-20201014215450237

(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才会进行路由

测试查看

image-20201014221117326

当我们的请求携带设置的请求头时

image-20201014221147229

需要注意的是,我们的请求头的值也是支持正则表达式的,例如

- Header=Authentication,\d+

如此设置呢,则要求我们的请求必须含有Authentication ,且值必须为一个或多个纯数字

image-20201014221743520

(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

无设置的参数请求

image-20201014230959207

有gateway路由谓词设置的参数请求
image-20201014231048907

设置固定参数名,且值设为正则匹配

spring:
  cloud:
    gateway:
      routes:
        #服务名路由 负载均衡
        - id: server-product
          uri: lb://demo-product
          predicates:
            - Query=name,A.

那么此设置呢,则要求请求中必须携带参数名为name,且值必须以A开头

image-20201014232143467

(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也可以**. 部分可作为模糊

测试:

image-20201015214206143

按照谓词设置,传入正确格式主机名:

image-20201015214306227

(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功能…敬请期待

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值