问题

进行以下路由配置,当调用/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支持以下三种路由配置

  • ?:匹配任意的单个字符
  • *:匹配任意数量的字符
  • **:匹配任意数量的字符,支持多级目录