解决spring gateway+eureka,自定义路由规则不生效的问题和思考.

103 阅读3分钟

背景

 项目使用了spring gateway+eureka,因业务迭代,既要兼容历史业务又要最小改动,所以就想在gateway侧进行自定义过滤器,达到客户端在不发版的情况下,对同一个接口下不同用户进行前置逻辑处理.

现状和排查

 梳理了下目前网关的配置,使用了的properties格式的路由配置,每个项目都对路径添加StripPrefix配置(建议按照官方使用yaml格式):

spring.cloud.gateway.routes[0].uri = lb://aaa-service

spring.cloud.gateway.routes[0].predicates[0] = Path=/doc/aaa-service/**

spring.cloud.gateway.routes[0].filters[0] = StripPrefix=2

  • 疑问1: 经过与客户端确认,发现调用格式为网关域名+aaa-service/** 的格式,当时就觉得很奇怪为什么配置的路径有/doc,但是却能正常的路由到对应的项目.
  • 疑问2: 由于需要在对应路径添加自定义局部过滤器,于是我就进行了以下配置: spring.cloud.gateway.routes[1].predicates[0] = Path=/aaa-service/order/,/aaa-service/get/ spring.cloud.gateway.routes[1].filters[0] = StripPrefix=1 spring.cloud.gateway.routes[1].filters[1].name = CusModifyRequestBody 实际测试结果却始终不生效.

于是进行查询ai和相关资料,通过/actuator/gateway/routes发现有每个项目有以下配置:

"filters": [ "[[RewritePath /aaa-service/?(?\u003Cremaining\u003E.*) = '/${remaining}'], order = 1]" ]

查看源码RewritePathGatewayFilterFactory是gateway内置的过滤器,但是extends AbstractGatewayFilterFactory<RewritePathGatewayFilterFactory.Config> 不应该为全局过滤器呀,而且也没有显式配置.为啥会自动加上这个过滤器?

最终排查,发现是eureka配置导致的,本着对好奇心理,就去查阅了一些文档,在官方文档中找到了以下描述:

image.png

如果微服务的项目很多,每个服务就需要手动配置路由,我想这就是开发者的初衷吧.

疑问2是解决了,那么疑问1又怎么解释?doc?我就联想到使用的swagger,事实也确实如此,目的是想在gateway做一个统一的接口文档,前端只需要访问gateway的域名就可以下拉选择对应项目的接口文档了.估计当时就是因为服务发现默认路由才添加了/doc前缀的,为了访问swagger的文档接口做的处理.

既然了解清楚了,那就回归到本次要添加的路由配置,当存在不同id的route,gateway只会让一个生效,如何让自定义的路由规则优于服务发现的呢?

  1. 方案一:关闭服务路由发现,自定义配置历史路由.缺点:配置过多,人工配置容易出问题.优点:性能会好点,尤其在大量请求,毕竟用了正则替换的.
  2. 方案二:覆盖默认配置,添加order属性,spring.cloud.gateway.routes[x].order = -1,让自定义的路由小于默认配置的order.

 最后使用方案二解决的,同时也可以灵活的配置路径添加自定义的filter,解决完这个问题,我最后也思考了下,因为在排查过程中使用了ai,也花费了一些时间,给我的感觉就是,在自己不了解这些配置,原理,或者是遇到问题,没有思路的情况下,使用ai,其他资料,也不容易找到问题的本质.而且ai和网上资料有些也不完全正确,每个项目也不一样.只有思路正确,脑海中有怀疑大概率出错的地方,经过排除验证,才能解决.这是成为资深开发必须要锻炼的能力.善于发现问题,思考,总结才能让自己成长.