搭建環境說明:
zookeeper #作為服務的註冊中心
zero #服務消費者,一個實例
one #服務的提供者,創建了二個實例。
在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服務中我定義瞭如下接口:
現象說明:
我在瀏覽器中,訪問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的時候接口返回失敗,導致認為服務器不可用。