微服務Spring Cloud17_負載均衡Ribbon6

花溪月影發表於2024-05-08

一、概述

 在剛才的案例中,我們啟動了一個 user-service ,然後透過DiscoveryClient來獲取服務例項資訊,然後獲取ip和埠來訪問。

 但是實際環境中,往往會開啟很多個 user-service 的叢集。此時獲取的服務列表中就會有多個,到底該訪問哪一個呢?

 一般這種情況下就需要編寫負載均衡演算法,在多個例項列表中進行選擇。

 不過Eureka中已經整合了負載均衡元件:Ribbon,簡單修改程式碼即可使用。

 什麼是Ribbon:

  

 接下來,我們就來使用Ribbon實現負載均衡。

二、啟動兩個服務例項

 首先我們配置啟動兩個 user-service 例項,一個9091,一個9092。

  

 Eureka監控皮膚:

  

二、開啟負載均衡

 因為Eureka中已經整合了Ribbon,所以我們無需引入新的依賴。

 直接修改 consumer-demo\src\main\java\com\itheima\consumer\ConsumerApplication.java

 在RestTemplate的配置方法上新增 @LoadBalanced 註解:

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

 修改 consumer-demo\src\main\java\com\itheima\consumer\controller\ConsumerController.java 呼叫方式,不再手動獲取ip和埠,而是直接透過服務名稱呼叫;

@GetMapping("{id}")
public User queryById(@PathVariable("id") Long id){
    String url = "http://user-service/user/" + id;
    User user = restTemplate.getForObject(url, User.class);
    return user;
}

訪問頁面,檢視結果;並可以在9091和9092的控制檯檢視執行情況:

瞭解:Ribbon預設的負載均衡策略是輪詢。SpringBoot也幫提供了修改負載均衡規則的配置入口在consumerdemo的配置檔案中新增如下,就變成隨機的了:

user-service:
 ribbon:
   NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

格式是: {服務名稱}.ribbon.NFLoadBalancerRuleClassName

三、原始碼跟蹤

 為什麼只輸入了service名稱就可以訪問了呢?之前還要獲取ip和埠。

 顯然是有元件根據service名稱,獲取到了服務例項的ip和埠。因為 consumer-demo 使用的是RestTemplate, spring的負載均衡自動配置類LoadBalancerAutoConfiguration.LoadBalancerInterceptorConfig 會自動配置負載均衡攔截器(在spring-cloud-commons-**.jar包中的spring.factories中定義的自動配置類),它就是 LoadBalancerInterceptor ,這個類會在對RestTemplate的請求進行攔截,然後從Eureka根據服務id獲取服務列 表,隨後利用負載均衡演算法得到真實的服務地址資訊,替換服務id。

 我們進行原始碼跟蹤:

  

 繼續跟入execute方法:發現獲取了9092埠的服務

  

 再跟下一次,發現獲取的是9091、9092之間切換:

  

 多次訪問 consumer-demo 的請求地址;然後跟進程式碼,發現其果然實現了負載均衡。

相關文章