Spring Cloud Gateway---路由匹配规则

写在前面 本文参考以下文章,请参考原文

springcloud(十五):服务网关 Spring Cloud GateWay 入门

 Predicate & Spring Cloud Gateway 路由匹配规则

Predicate 来源于 Java 8,是 Java 8 中引入的一个函数,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。

在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各种路由匹配规则,有通过 Header、请求参数等不同的条件来进行作为条件匹配到对应的路由。

Spring Cloud Gateway--网关路由 简单示例了Spring Cloud Gateway的路由功能,现在讲一下Spring Cloud Gateway的路由规则。

1.通过时间匹配(datetime)

通过配置predicated 的 Before ,After ,Between 等属性,可以实现限制路由转发的时间段。时间对比:Spring 是通过 ZonedDateTime 来对时间进行的对比,ZonedDateTime 是 Java 8 中日期时间功能里,用于表示带时区的日期与时间信息的类,ZonedDateTime 支持通过时区来设置时间,中国的时区是:Asia/Shanghai

  • Before Route Predicate 刚好相反,在某个时间之前的请求的请求都进行转发
  • After Route Predicate 是指在这个时间之后的请求都转发到目标地址
  • Between Route Predicate 只有在这段时间内的请求才进行转发

Spring Cloud Gateway--网关路由 的例子基础上修改application.yml如下,就表示在这个时间之前可以进行路由,在这时间之后停止路由,修改完之后重启项重新启动网关服务,访问http://localhost:8080/discoveryClient,页面会报 404 没有找到地址

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Before=2020-12-01T06:06:06+08:00[Asia/Shanghai]

修改application.yml如下,就表示在这个时间之后的时间可以进行路由,修改完之后重启项重新启动网关服务,访问http://localhost:8080/discoveryClient,会自动路由到 http://localhost:2001/discoveryClient

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - After=2020-21-01T06:06:06+08:00[Asia/Shanghai]

修改application.yml如下,就表示只有这个时间段内 可以进行路由,修改完之后重启项重新启动网关服务,访问http://localhost:8080/discoveryClient,会自动路由到 http://localhost:2001/discoveryClient

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Between=2020-12-01T06:06:06+08:00[Asia/Shanghai], 2020-12-16T06:06:06+08:00[Asia/Shanghai]

2.通过Cookie匹配(Cookie)

Cookie Route Predicate 可以接收两个参数,一个是 Cookie name ,一个是正则表达式,路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Cookie=name, mtest

使用curl命令测试,可以看到带cookie的请求可以正确路由,正常获取到页面返回值,不带cookie的请求会404

C:\Users\mm>curl http://localhost:8080/discoveryClient --cookie "ityouknow=kee.e"
Services: []
C:\Users\mm>curl http://localhost:8080/discoveryClient
{"timestamp":"2020-12-09T03:48:44.034+00:00","path":"/discoveryClient","status":404,"error":"Not Found","message":null,"requestId":"80c9666b-1"}

3.通过 Header 属性匹配(Header)

Header Route Predicate也是接收 2 个参数,一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Header=X-Request-Id, \d+

使用curl命令测试,可以看到 Header 属性值和正则表达式匹配的请求可以正确路由,否则会404

C:\Users\mm>curl http://localhost:8080/discoveryClient -H "X-Request-Id:666666"
Services: []
C:\Users\mm>curl http://localhost:8080/discoveryClient -H "X-Request-Id:IO"
{"timestamp":"2020-12-09T07:10:48.753+00:00","path":"/discoveryClient","status":404,"error":"Not Found","message":null,"requestId":"07aaa6b2-2"}

4.通过Host匹配(Host)

Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。它通过参数中的主机地址作为匹配规则

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Host=**.baidu.com

使用curl命令测试,可以看到  去掉 host 参数或者host参数值和规则不匹配 会报 404 错误

C:\Users\mm>curl http://localhost:8080/discoveryClient -H "Host: cn.baidu.com"
Services: []
C:\Users\mm>curl http://localhost:8080/discoveryClient -H "Host: www.baidu.com"
Services: []
C:\Users\mm>curl http://localhost:8080/discoveryClient -H "Host: www.baid.com"
{"timestamp":"2020-12-09T08:08:35.150+00:00","path":"/discoveryClient","status":404,"error":"Not Found","message":null,"requestId":"3e93a018-4"}
C:\Users\mm>curl http://localhost:8080/discoveryClient
{"timestamp":"2020-12-09T08:08:40.223+00:00","path":"/discoveryClient","status":404,"error":"Not Found","message":null,"requestId":"e8d97b0c-5"}

 5.通过请求方式匹配(Method)

可以通过是 POST、GET、PUT、DELETE 等不同的请求方式来进行路由

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Method=GET

curl 分别测试GET , POST 方法,看效果如下。 curl默认是GET方法

C:\Users\mm>curl http://localhost:8080/discoveryClient
Services: []
C:\Users\mm>curl -X POST http://localhost:8080/discoveryClient
{"timestamp":"2020-12-09T08:13:14.466+00:00","path":"/discoveryClient","status":404,"error":"Not Found","message":null,"requestId":"3cea7707-2"}

6.通过请求路径匹配(Path)

Path Route Predicate 接收一个匹配路径的参数来判断是否走路由,以上的例子都用了Path匹配

7.通过请求参数匹配(QueryParam)

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

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Query=smile

重启网关服务,访问http://localhost:8080/discoveryClient?smile=x, 可以正确路由到 http://localhost:2001/discoveryClient;访问http://localhost:8080/discoveryClient?smile=x&id=2, 可以正确路由到 http://localhost:2001/discoveryClient;也就是说只要请求中包含 smile 属性的参数即可匹配路由。

7.2 将 Query 的值以键值对的方式进行配置,这样在请求过来时会对属性值和正则进行匹配,匹配上才会走路由

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Query=keep, pu.

重启网关服务,访问 http://localhost:8080/discoveryClient?keep=pu2,可以正确路由到 http://localhost:2001/discoveryClient;访问 http://localhost:8080/discoveryClient?keep=pu23 ,返回404。也就是说:只有当请求中包含 keep 属性并且参数值是以 pu 开头的长度为三位的字符串才会进行匹配和路由

7.3 匹配多个请求参数

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Query=smile
        - Query=keep, pu.

重启网关服务,访问 http://localhost:8080/discoveryClient?smile=4&keep=pu8,可以正确路由到 http://localhost:2001/discoveryClient

8.通过请求 ip 地址进行匹配(RemoteAddr)

 Predicate 也支持通过设置某个 ip 区间号段的请求才会路由,RemoteAddr Route Predicate 接受 cidr 符号(IPv4 或 IPv6 )字符串的列表(最小大小为1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)

如果请求的远程地址是 192.168.1.10,则此路由将匹配。

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - RemoteAddr=192.168.1.1/24

可以将此地址设置为本机的 ip 地址进行测试

C:\Users\mm>curl http://localhost:8080/discoveryClient

 9.组合Predicate 

其实以上例子都用了- Path 和 其它Predicate的组合使用。当各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
      - id: neo_route
        uri: http://localhost:2001/
        predicates:
        - Path=/discoveryClient
        - Before=2020-12-01T06:06:06+08:00[Asia/Shanghai]
        - Cookie=name, mtest
        - Query=smile

10.一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发

上一篇:Applications Manager—打造最佳云监控策略


下一篇:机器学习应用深度剖析