问题
进行以下路由配置,当调用/financial_order/calculation
时,无法将请求转发到http://service-financial-product:8080
;zuul应是按从上至下,第一个匹配到的规则进行转发,所以原则上应请求至http://service-financial-product:8080
financial_calculation:
path: /financial_order/calculation
url: http://service-financial-product:8080/financial_product
stripPrefix: false
financial_order_service:
path: /financial_order/**
url: http://service-finance-order:8080
stripPrefix: false
原因
项目中添加了consul自动监听配置文件变化,自动修改刷新本地配置的功能,consul刷新配置文件时,使用的是Properties,Properties是用hashtable实现的,不保证顺序
而直接读yaml配置文件没问题是因为配置是通过 ZuulProperties 类 @ConfigurationProperties("zuul")实现的,其中routes是LinkedHashMap
读取yaml配置文件
- zuul的入口为ZuulController,由此会进入ZuulServlet,在该serivce方法中,会执行preRoute,route,postRoute三种类型的过滤器
- 在preRoute PreDecorationFilter中会将匹配到的Route信息set到RequestContext,包括routeHost
- 在PreDecorationFilter中会通过SimpleRouteLocator匹配路由,而SimpleRouteLocator中的路由来自于ZuulProperties.routes
- ZuulProperties是一个配置类,由@ConfigurationProperties("zuul")标注
- 在route中存在一个SimpleHostRoutingFilter,在该Filter中,会从RequestContext中取出host,然后会通过httpclient调用新的host接口,并获取响应
consul刷新配置
- consul通过ConsulPropertySourceLocator加载配置,该实现使用的是properties,是无序的,故刷新后出现问题
附
spring支持以下三种路由配置
- ?:匹配任意的单个字符
- *:匹配任意数量的字符
- **:匹配任意数量的字符,支持多级目录