RestTemplate+Ribbon實現客戶端負載均衡的一個奇葩問題

搭建環境說明:

zookeeper #作為服務的註冊中心

zero #服務消費者,一個實例

one #服務的提供者,創建了二個實例。

在zookeeper中註冊成功,如下圖所示:

RestTemplate+Ribbon實現客戶端負載均衡的一個奇葩問題

zookeeper

在zero服務中我定義了一個RestTemplate:

<code>/** 
* @LoadBalanced註解,增加Ribbon功能,實現客戶端負載均衡 
* @param builder * 
  @return 
  */
@Bean
@LoadBalanced
 public RestTemplate restTemplate(RestTemplateBuilder builder) {
   return  builder.build();
}/<code>

在zero服務中定義了一個訪問one服務中的方法:

<code>@Autowired
private RestTemplate restTemplate;
@GetMapping("/getOne")
public void getOne(){
    //url會在zookeeper註冊中心上通過name進行查找,restTemplate通過name來找服務,是依賴ribbon,所以RestTemplate初始化要加上@LoadBalanced    
  String url="http://one/commonOne/getOne";    
  String result=restTemplate.getForObject(url,String.class);   
  log.info(result);
}/<code>

在one服務中我定義瞭如下接口:

RestTemplate+Ribbon實現客戶端負載均衡的一個奇葩問題

現象說明:

我在瀏覽器中,訪問zero的這個服務接口連接:http://localhost:9998/zookeeperServices/getOne

這個接口的功能就是去one服務的getOne接口,因為one服務在zookeeper中定義了兩個實例,所以會根據負載均衡策略,隨機訪問到,而打印出不同的端口號。但是在調用過程中,一直報錯,提示可用的服務列表為空。

根本原因:

在Ribbon拿到one的實例列表後,本例子是2個,會調用ping方法去ping目標主機,ping的url是 http://ip:端口/health,這是spring boot給我們默認暴露的health端點,由於我在one服務的配置文件中定義瞭如下的配置management.endpoints.web.base-path=/actuator,就是給暴露的端點增加了base-path,導致在ping的時候接口返回失敗,導致認為服務器不可用。


分享到:


相關文章: