spring cloud2022.0网关路由功能验证及配置

1. 路由排序

如下配置,多个路由规则的覆盖范围有重叠. 路由生效时,会按照order进行优先级排序.order越小,优先级越高.

因为适配某一个路由后,请求就被路由到业务服务了,所以只有一个路由规则会生效.

注意:如未显式指定order,其默认值为0.

基础配置

# 调用demoService的路由配置# 调用
demoService
的路由配置
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        – id: base-routeA
          uri: lb://serverA
          order: 3
          filters:
            – StripPrefix=1
          predicates:
            – Before=2023-05-01T00:00:00+08:00[Asia/Shanghai]
 
        – id: base-routeB
          uri: lb://serverB
          order: 2
          filters:
            – StripPrefix=1
          predicates:
            – Before=2023-05-01T00:00:00+08:00[Asia/Shanghai]
 
        – id: base-routeC
          uri: lb://serverC
          order: 1
          filters:
            – StripPrefix=1
          predicates:
            – Before=2023-05-01T00:00:00+08:00[Asia/Shanghai]

效果展示与说明

请求配置结果
/demo/helloserviceC order=-1路由到serviceC
/demo/helloserviceA order不配置serviceC order=1路由到serviceA

2. 时间路由

适用于老服务下线,新服务上线,限时活动等场景

predicates里的时间限制,定义了该条规则生效的时间段.所以可以提前配置,到了活动时间自动生效

基础配置

同路由排序的配置

效果展示与说明

在上述routes的基础上,修改predicates

请求配置结果
/demo/helloserviceC order=-1predicates:- Before=2022-05-01T00:00:00+08:00[Asia/Shanghai]routeC不生效,由routeA规则,路由到serviceA
/demo/helloserviceC order=-1predicates:- Before=2023-05-01T00:00:00+08:00[Asia/Shanghai]路由到serviceC
/demo/helloserviceC order=-1predicates:- Between=2022-05-01T00:00:00+08:00[Asia/Shanghai], 2023-05-01T00:00:00+08:00[Asia/Shanghai]路由到serviceC
/demo/helloserviceC order=-1其他order不配置predicates:- Between=2022-05-01T00:00:00+08:00[Asia/Shanghai], 2023-03-01T00:00:00+08:00[Asia/Shanghai]routeC 不生效由routeA 路由到serviceA
/demo/helloserviceC order=-1predicates:- After=2022-05-01T00:00:00+08:00[Asia/Shanghai] 路由到服务C
/demo/helloserviceC order=-1predicates:- After=2023-05-01T00:00:00+08:00[Asia/Shanghai] routeC的After条件不生效,使用了routeA做路由,路由到serviceA

3. 前缀路由

可以根据path前缀不同,路由到不同的业务服务.这是我们微服务场景下使用到的最基础的路由功能

基础配置

# 调用demoService的路由配置s# 调用
demoService
的路由配置
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        – id: base-routeA
          uri: lb://serverA
          filters:
            – StripPrefix=1
          predicates:
            – Path=/a/**
 
        – id: base-routeB
          uri: lb://serverB
          filters:
            – StripPrefix=1
          predicates:
            – Path=/b/**
 
        – id: base-routeC
          uri: lb://serverC
          filters:
            – StripPrefix=1
          predicates:
            – Path=/c/**
        # predicates不能为空
        – id: default-route
          uri: lb://serverA
          order: -1
          filters:
            – StripPrefix=1
          predicates:
            – Path=/**

注意:predicates需要显示配置,为空或者不配置,无法解析路由.

效果展示与说明

请求配置结果
/demo/hello无改变匹配到default-routes,路由到serviceA
/a/hello无改变请求到serviceA
/b/hello无改变请求到serviceB
/c/hello无改变请求到serviceC
   

4.Header路由

spring gateway可以通过header里的信息匹配路由规则.

在我们灰度发布过程中,常利用header来进行灰度判断

基础配置

# 调用
demoService
的路由配置
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        – id: base-routeA
          uri: lb://serverA
          filters:
            – StripPrefix=1
          predicates:
            – Header=X-Request-Id, \d+
 
        – id: base-routeB
          uri: lb://serverB
          filters:
            – StripPrefix=1
          predicates:
            – Header=X-Request-Id, abc
 
        – id: base-routeC
          uri: lb://serverC
          order: -2
          filters:
            – StripPrefix=1
          predicates:
            – Path=/c/**
            – Header=X-Request-Id, \d+

效果展示与说明

请求配置结果
/demo/hello
X-Request-Id:123
无改变header里的requestId字段为数字,路由到serviceA
/demo/hello
X-Request-Id:abc
无改变header匹配到固定值”abc”路由到serviceB
/c/hello
X-Request-Id:123
无改变因为routeC的优先级高,在请求匹配了path和header的前提下, 通过routeC 路由到了C服务
/c/hello
X-Request-Id:abc
无改变不满足routeC的路由条件,请求到serviceB
/c/hello
X-Request-Id:123
routeC的order设为0路由到serviceA
/c/hello
X-Request-Id:abc
routeC的order设为0路由到serviceB

5.Cookie路由

同样是在灰度发布的场景下,除了使用header隐式的传递参数,也可以在cookie里带参数.

Header参数通常可以是每个请求都不同的,而cookie则会适配域名,有相对较长的过期时间

基础配置

# 调用
demoService
的路由配置
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        – id: base-routeA
          uri: lb://serverA
          filters:
            – StripPrefix=1
          predicates:
            – Cookie=env, gray
 
        – id: base-routeB
          uri: lb://serverB
          filters:
            – StripPrefix=1
          predicates:
            – Path=/b/**
 
        – id: base-routeC
          uri: lb://serverC
          # order: -2
          filters:
            – StripPrefix=1
          predicates:
            – Path=/**

效果展示与说明

请求配置结果
/c/helloCookie_env=gray;无改变cookie的k,v都匹配,路由到serverA
/c/helloCookie_env=white;无改变cookie不匹配,根据规则routeC,路由到serverC
/b/helloCookie_env=gray;routeB的 order: -1优先判断routeB,满足predicates条件,路由到serverB

注意

完整cookie为Cookie_env=gray; Path=/; Expires=Thu, 07 Mar 2024 01:42:14 GMT;

为突出重点,表格中只展示Cookie_env=gray;

适配cookie时,需要注意cookie域名与请求域名相匹配. 127.0.0.1 与 localhost是两个不同的域名

6.根据域名路由

在复杂的微服务系统中,可能一套微服务对应多个域名. 比如 hr.acabridge.com/login 需要人才服务来处理这个登录请求. admin.acabridge.com/login 的登录请求需要admin后台服务来处理.

基础配置

修改hosts

127.0.0.1       hr.local.sunhaoyuan.com
127.0.0.1       admin.local.sunhaoyuan.com

路由配置:

# 调用
demoService
的路由配置
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        – id: base-routeA
          uri: lb://serverA
          filters:
            – StripPrefix=1
          predicates:
            – Host=hr.local.acabridge.com
 
        – id: base-routeB
          uri: lb://serverB
          filters:
            – StripPrefix=1
          predicates:
            – Host=admin.**.acabridge.com
 
        – id: base-routeC
          uri: lb://serverC
          filters:
            – StripPrefix=1
          predicates:
            – Path=/**

效果展示与说明

请求配置结果
localhost:8080/demo/hello无改变路由到serverC
hr.local.acabridge.com:8080/demo/hello无改变路由到了serverC与预期不一致gateway获取的host数据:remoteAddress:/127.0.0.1:55113remoteHost:kubernetes.docker.internalhost:127.0.0.1
admin.local.acabridge.com:8080/demo/hello无改变路由到serverC与预期不一致remoteAddress:/127.0.0.1:58495remoteHost:kubernetes.docker.internalhost:127.0.0.1

注意

host可能会不准. 在多次代理之后,原来的host可能会丢失或修改.所以host也像ip一样,存在误判的问题. 所以多个域名 建议在dns层解析到不同的gateway集群,而不是请求到gateway之后再做路由.

本机测试时的host与postman输入的不一致,是因为本地的docker环境对发送到本机的网络请求都做了监听. 在生产环境中,也可能会出现被gateway服务本机或者前置服务(如WAF)修改的情况

7.根据RemoteAddr做路由

使用场景 可能是对某个ip做特殊处理.比如 gateway后面对接了两个微服务集群, 一个生产集群,一个演示集群.演示集群的接口会返回demo数据. 而我们的演示都会在一台固定ip的设备上进行.

此时就可以把这台演示机的请求都路由到演示集群;

基础配置

# 调用demoService的路由配置spring:  cloud:    gateway:      discovery:        locator:          enabled: # 调用
demoService
的路由配置
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        – id: base-routeA
          uri: lb://serverA
          filters:
            – StripPrefix=1
          predicates:
            – RemoteAddr=192.168.1.1/24
 
        – id: base-routeB
          uri: lb://serverB
          filters:
            – StripPrefix=1
          predicates:
            – RemoteAddr=127.0.0.1/24
 
        – id: base-routeC
          uri: lb://serverC
          filters:
            – StripPrefix=1
          predicates:
            – Path=/**

效果展示与说明

请求配置结果
localhost:8080/demo/hello无改变路由到serverC与预期不一致remoteAddress:0:0:0:0:0:0:0:1/[0:0:0:0:0:0:0:1]:60629host:[0:0:0:0:0:0:0:1]
127.0.0.1:8080/demo/hello无改变路由到了serverBremoteAddress:/127.0.0.1:60743host:127.0.0.1
hr.local.acabridge.com:8080/demo/hello无改变路由到serverB与预期不一致remoteAddress:/127.0.0.1:53354host:127.0.0.1

注意

remoteAddr与host类似,会受前置代理/本机代理影响,实际的路由匹配结果与预期可能不一致

8.根据请求方法类型路由

gateway支持 把GET/POST等请求类型路由到不同的服务.

该用法比较小众,可能的场景是: 服务重构过程中,某个接口不能做逻辑兼容,或者老接口不能下线&新老接口必须使用相同的path,而不是 /login/v1, /login/v2这种并存的接口

基础配置

# 调用
demoService
的路由配置
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        – id: base-routeA
          uri: lb://serverA
          filters:
            – StripPrefix=1
          predicates:
            – Method=GET,POST
 
        – id: base-routeB
          uri: lb://serverB
          filters:
            – StripPrefix=1
          predicates:
            – Method=DELETE
 
        – id: base-routeC
          uri: lb://serverC
          filters:
            – StripPrefix=1
          predicates:
            – Path=/**

效果展示与说明

请求配置结果
GET 127.0.0.1:8080/demo/hello无改变路由到serverA
POST127.0.0.1:8080/demo/hello无改变路由到serverA
DELETE127.0.0.1:8080/demo/hello无改变路由到serverB
PUT127.0.0.1:8080/demo/hello无改变路由到serverC前两个路由规则 都没匹配,执行到了兜底路由策略

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注