springCloud出现:Load balancer does not have available server for client: SERVICE-XXX的错误解决方法

我现在的框架结构大致是:前端请求,通过zuul转发到user的接口提供模块,user接口提供模块调用user服务模块的业务功能(feign调用),user服务的业务功能需要调用base服务模块的一个业务功能(手动调用),大致就是:前端请求->userApi->userService->baseService。这个流程在两个地方出现了此问题

1 在接口模块中出现此错误

如果在zuul直接代理的接口层(也就是zuul直接转发的那一层,我这里是user接口提供层,userApi)的application.yml中配置了负载均衡,则会出现此问题:

com.netflix.zuul.exception.ZuulException: Forwarding error
	at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.handleException(RibbonRoutingFilter.java:198) ~[spring-cloud-netflix-zuul-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.forward(RibbonRoutingFilter.java:173) ~[spring-cloud-netflix-zuul-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter.run(RibbonRoutingFilter.java:119) ~[spring-cloud-netflix-zuul-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:117) ~[zuul-core-1.3.1.jar:1.3.1]
-------------------------只截取了一些关键错误信息--------------------------------
Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: SERVICE-USERAPI
	at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
	at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
	at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180) ~[ribbon-loadbalancer-2.3.0.jar:2.3.0]
	at rx.Observable.unsafeSubscribe(Observable.java:10327) ~[rxjava-1.3.8.jar:1.3.8]
	at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94) ~[rxjava-1.3.8.jar:1.3.8]
	at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42) ~[rxjava-1.3.8.jar:1.3.8]

SERVICE-USERAPI是我的服务名,是因为我在userApi模块里配置了如下代码:

ribbon:
  eureka:
    enabled: true

zuul是有自己的反向代理和负载均衡功能,解决方法是把这句配置去掉就行。

2 在服务模块中出现此问题

有时候会在业务层的服务中调用其他服务提供者的服务,这时如果用手动调用服务的方式(使用feign调用时候也一样),如果在restTemplate上面开启了@LoadBalanced,但是在配置文件中未开启负载均衡,那么同样也会出现这个错误,解决方法如下:
1 在被调用的服务配置文件(这里是baseService的application.yml)中加上:

ribbon:
  eureka:
    enabled: true

2 同时开启restTemplate(userService里开启)的负载均衡能力

/**
 * springCloud相关的一些配置
 *
 * @author lgs
 */
@Configuration
public class SpringCloudConfig {

    /**
     * 服务调用工具
     *
     * @return
     * @LoadBalanced 让RestTemplate在请求时拥有客户端负载均衡的能力
     */
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

这两个配置加上之后,手动调用其他服务也会有负载均衡的能力(userService调用baseService里的服务):

 @Override
    public ResponseInfo findAllDataBase() {
        MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        multiValueMap.add("name", "lgs");
        //直接发送post请求
        ResponseInfo responseInfo = restTemplate.postForObject(ServiceEnum.SERVICE_BASE.getServicePath() + "/base/sayHello", multiValueMap, ResponseInfo.class);
        return responseInfo;
    }

记录错误,点滴成长。

你可能感兴趣的:(错误记录)