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/hello | serviceC order=-1 | 路由到serviceC |
/demo/hello | serviceA order不配置serviceC order=1 | 路由到serviceA |
2. 时间路由
适用于老服务下线,新服务上线,限时活动等场景
predicates里的时间限制,定义了该条规则生效的时间段.所以可以提前配置,到了活动时间自动生效
基础配置
同路由排序的配置
效果展示与说明
在上述routes的基础上,修改predicates
请求 | 配置 | 结果 |
/demo/hello | serviceC order=-1predicates:- Before=2022-05-01T00:00:00+08:00[Asia/Shanghai] | routeC不生效,由routeA规则,路由到serviceA |
/demo/hello | serviceC order=-1predicates:- Before=2023-05-01T00:00:00+08:00[Asia/Shanghai] | 路由到serviceC |
/demo/hello | serviceC order=-1predicates:- Between=2022-05-01T00:00:00+08:00[Asia/Shanghai], 2023-05-01T00:00:00+08:00[Asia/Shanghai] | 路由到serviceC |
/demo/hello | serviceC 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/hello | serviceC order=-1predicates:- After=2022-05-01T00:00:00+08:00[Asia/Shanghai] | 路由到服务C |
/demo/hello | serviceC 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前两个路由规则 都没匹配,执行到了兜底路由策略 |