Spring Cloud Gateway 中 Predict 断言条件(转发规则) 介绍

2021-10-13 0 By admin

Predicate 来源于 Java 8的接口,是 Java 8 中引入的一个函数,Predicate 接受一个输入参数,返回一个布尔值结果。
该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。
在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各种路由匹配规则,有通过 Header、请求参数等不同的条件来进行作为条件匹配到对应的路由。

Spring Cloud Gateway 内置了许多 Predict,这些Predict的源码在org.springframework.cloud.gateway.handler.predicate 包中,网上有一张图总结了 Spring Cloud 内置的几种 Predicate 的实现。

SpringCloud Gateway Predicate
SpringCloud Gateway Predicate

在上图中,有很多类型的 Predicate,

  1. 时间类型的Predicated(AfterRoutePredicateFactory BeforeRoutePredicateFactory BetweenRoutePredicateFactory),当只有满足特定时间要求的请求会进入到此predicate中,并交由router处理;
  2. cookie类型的CookieRoutePredicateFactory,指定的cookie满足正则匹配,才会进入此router;
  3. 以及host、method、path、querparam、remoteaddr类型的predicate,每一种predicate都会对当前的客户端请求进行判断,是否满足当前的要求,如果满足则交给当前请求处理。

如果有很多个Predicate,并且一个请求满足多个Predicate,则按照配置的顺序第一个生效。

一、Predicate 常见列表

规则 实例 说明
Path – Path=/gate/,/rule/ ## 当请求的路径为gate、rule开头的时,转发到http://localhost:9023服务器上
Before – Before=2017-01-20T17:42:47.789-07:00[America/Denver] 在某个时间之前的请求才会被转发到 http://localhost:9023服务器上
After – After=2017-01-20T17:42:47.789-07:00[America/Denver] 在某个时间之后的请求才会被转发
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.hd123.com 当主机名为www.hd123.com的时候直接转发到http://localhost:9023服务器上
Method – Method=GET 只有GET方法才会匹配转发请求,还可以限定POST、PUT等请求方式

二、Predicate 实践介绍

2.1、通过请求参数匹配

Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式。

server:
  port: 8080
spring:
  application:
  	 name: api-gateway
  cloud:
    gateway:
      routes:
        -id: gateway-service
          uri: https://www.baidu.com
          order: 0
          predicates:
            -Query=smile

这样配置,只要请求中包含 smile 属性的参数即可匹配路由。
使用 curl 测试,命令行输入:
curl localhost:8080?smile=x&id=2
经过测试发现只要请求汇总带有 smile 参数即会匹配路由,不带 smile 参数则不会匹配。

2.2、 Predicates 组合使用

server:
  port: 8080
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: gateway-service
          uri: https://www.baidu.com
          order: 0
          predicates:
            - Host=**.foo.org
            - Path=/headers
            - Method=GET
            - Header=X-Request-Id, \d+
            - Query=foo, ba.
            - Query=baz
            - Cookie=chocolate, ch.p

各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。
一个请求满足多个路由的断言条件时,请求只会被首个成功匹配的路由转发。