天天看點

springCloud出現:Load balancer does not have available server for client: SERVICE-XXX的錯誤解決方法1 在接口子產品中出現此錯誤2 在服務子產品中出現此問題

我現在的架構結構大緻是:前端請求,通過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;
    }
           

記錄錯誤,點滴成長。

繼續閱讀