问题概述:
在基于微服务架构风格的项目开发过程中,使用Spring Cloud Zuul 来实现服务请求的代理、路由以及过滤的操作,在配置使用过程中遇到了一个梗,异常信息“ Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: new ” ,部分详细信息如下:
com.netflix.zuul.exception.ZuulException: Forwarding error
at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.handleException(RibbonRoutingFilter.java:183) ~[spring-cloud-netflix-core-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.forward(RibbonRoutingFilter.java:158) ~[spring-cloud-netflix-core-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.run(RibbonRoutingFilter.java:106) ~[spring-cloud-netflix-core-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:112) ~[zuul-core-1.3.0.jar:1.3.0]
at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:193) ~[zuul-core-1.3.0.jar:1.3.0]
at com.netflix.zuul.FilterProcessor.runFilters(FilterProcessor.java:157) ~[zuul-core-1.3.0.jar:1.3.0]
at com.netflix.zuul.FilterProcessor.route(FilterProcessor.java:118) ~[zuul-core-1.3.0.jar:1.3.0]
at com.netflix.zuul.ZuulRunner.route(ZuulRunner.java:96) ~[zuul-core-1.3.0.jar:1.3.0]
at com.netflix.zuul.http.ZuulServlet.route(ZuulServlet.java:116) ~[zuul-core-1.3.0.jar:1.3.0]
at com.netflix.zuul.http.ZuulServlet.service(ZuulServlet.java:81) ~[zuul-core-1.3.0.jar:1.3.0]
at org.springframework.web.servlet.mvc.ServletWrappingController.handleRequestInternal(ServletWrappingController.java:157) [spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.cloud.netflix.zuul.web.ZuulController.handleRequest(ZuulController.java:44) [spring-cloud-netflix-core-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50) [spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) [spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) [spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) [spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) [javax.servlet-api-3.1.0.jar:3.1.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [javax.servlet-api-3.1.0.jar:3.1.0]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:206) [websocket-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110) [spring-boot-actuator-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108) [spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106) [spring-boot-actuator-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) [jetty-security-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473) [jetty-servlet-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.Server.handle(Server.java:561) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:334) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) [jetty-server-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) [jetty-io-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:104) [jetty-io-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) [jetty-io-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:679) [jetty-util-9.4.7.v20170914.jar:9.4.7.v20170914]
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:597) [jetty-util-9.4.7.v20170914.jar:9.4.7.v20170914]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_40]
Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: new
at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2]
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2]
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180) ~[ribbon-loadbalancer-2.2.2.jar:2.2.2]
at rx.Observable.unsafeSubscribe(Observable.java:10211) ~[rxjava-1.1.10.jar:1.1.10]
部分截图如下:
解决办法:
经过摸索排查,发现配置 zuul 路由的时候,配置错了,通过查看 Netfix Zuul 的源码,需要明确一点的是,路由的配置是 K-V 的这样一个数据结构,导致这个错误的原因就是 Key 的前缀不一致导致的,这样在 zuul 不能正常的匹配到路由,错误以前的写法如下:
zuul:
prefix: /etcp # 添加公共的前缀
ignored-services: "*" # 忽略多个服务ID,使用*号,注意需要添加双引号哟,否则是char类型的,会报错,当然还可以以集合的形式进行忽略指定的多个服务ID
routes:
old.serviceId: microservice-provider
new.path: /manager/**
正确的写法:
zuul:
prefix: /etcp # 添加公共的前缀
ignored-services: "*" # 忽略多个服务ID,使用*号,注意需要添加双引号哟,否则是char类型的,会报错,当然还可以以集合的形式进行忽略指定的多个服务ID
routes:
microservice.serviceId: microservice-provider
microservice.path: /manager/**
总结:其中路由 Key 的前缀必须一致,后缀固定的 serviceId 和 path ,可以去看看 Netfix Zuul 的相关源码,绝对能找到答案的,遗留一个问题:zuul:igored-services 配置多个路径,看了哈源码,其类型是 set 的集合,只需要特定的几个就行了,在实际的生产环境中非常有用的。
好了,关于 com.netflix.client.ClientException: Load balancer does not have available server for client: 的解决办法 就写到这儿了,如果还有什么疑问或遇到什么问题欢迎扫码提问,也可以给我留言哦,我会一一详细的解答的。
歇后语:“ 共同学习,共同进步 ”,也希望大家多多关注CSND的IT社区。
作 者: | 华 仔 |
联系作者: | [email protected] |
来 源: | CSDN (Chinese Software Developer Network) |
原 文: | https://blog.csdn.net/Hello_World_QWP/article/details/86611665 |
版权声明: | 本文为博主原创文章,请在转载时务必注明博文出处! |