Zuul路由与Ribbon listOfServers(无Eureka)映射异常问题
解决Zuul+Ribbon路由路径丢失导致404的问题
你的问题核心在于使用Ribbon时,Zuul的路径转发逻辑和直接配置url的行为不一样。我们先拆解下原因,再给出具体的解决方案:
为什么直接用url能正常工作?
你原来的配置:
zuul: routes: restful-service: path: /restful-service/** url: http://host2:port2/rest-example
当请求http://host1:port1/restful-service/app1时,Zuul会自动把path中匹配到的后缀(也就是/app1)追加到你配置的url后面,最终转发到http://host2:port2/rest-example/app1,这完全符合你的预期。
用Ribbon时为什么会404?
当你切换到Ribbon配置(指定serviceId+禁用Eureka)时,Zuul默认的逻辑是:去掉path中的前缀(/restful-service),把剩下的路径直接追加到Ribbon服务的根路径(也就是http://host2:port2/),所以请求会变成http://host2:port2/app1——而你的实际服务是部署在/rest-example上下文下的,自然会返回404。
正确的解决方案:添加路径重写
我们需要让Zuul帮我们把路径重写为包含目标服务的上下文路径/rest-example,具体配置如下:
# Zuul路由配置 zuul: routes: restful-service: path: /restful-service/** # 匹配客户端请求的路径 serviceId: rest-example-service # 自定义的Ribbon服务ID # 重写路径:把/restful-service/后的内容转到/rest-example下 rewritePath: /restful-service/(?<segment>.*) /rest-example/${segment} # 禁用Ribbon的Eureka自动发现 ribbon: eureka: enabled: false # 指定Ribbon服务对应的服务器列表 rest-example-service: ribbon: listOfServers: host2:port2
配置解释
rewritePath用正则表达式捕获/restful-service/后面的所有内容(命名为segment),然后替换为/rest-example/${segment}。这样访问/restful-service/app1时,路径会被重写为/rest-example/app1。- Ribbon会根据
serviceId找到你配置的host2:port2,最终转发到http://host2:port2/rest-example/app1,和你用url配置的效果完全一致。
其他可选方案
如果你的Spring Cloud版本较新,也可以用path和serviceId结合stripPrefix+prefix的方式,但rewritePath是最直观且不容易出错的方案。
内容的提问来源于stack exchange,提问作者Prokopatti
相关产品推荐
相关产品推荐

