1. 程式人生 > 實用技巧 >Ribbon元件介紹和刨析

Ribbon元件介紹和刨析

本片簡略刨析,詳解轉到https://www.jianshu.com/p/1bd66db5dc46

簡介

  Spring Cloud Ribbon是一個基於HTTP和TCP的客戶端負載均衡工具,它基於Netflix Ribbon實現。通過Spring Cloud的封裝,可以讓我們輕鬆地將面向服務的REST模版請求自動轉換成客戶端負載均衡的服務呼叫。Spring Cloud Ribbon雖然只是一個工具類框架,它不像服務註冊中心、配置中心、API閘道器那樣需要獨立部署,但是它幾乎存在於每一個Spring Cloud構建的微服務和基礎設施中。因為微服務間的呼叫,API閘道器的請求轉發等內容,實際上都是通過Ribbon來實現的,包括後續我們將要介紹的Feign,它也是基於Ribbon實現的工具。所以,對Spring Cloud Ribbon的理解和使用,對於我們使用Spring Cloud來構建微服務非常重要。   通過引入Ribbon實現了服務消費者的客戶端負載均衡功能,其中,我們使用了非常有用的物件RestTemplate。該物件會使用Ribbon的自動化配置,同時通過配置@LoadBalanced還能夠開啟客戶端負載均衡。
@Bean
@LoadBalanced 
//使用ribbon public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); return restTemplate; }

Ribbon分析

從@LoadBalanced註解碼的註釋中,可以知道該註解用來給RestTemplate標記,以使用負載均衡的客戶端(LoadBalancerClient)來配置它。

org.springframework.cloud.client.loadbalancer.LoadBalancerClient

下載原始碼後看到

▪️為了給一些系統使用,建立一個帶有真實host和port的URI。
▪️一些系統使用帶有原服務名代替host的URI,比如http:
//myservice/path/to/service。 ▪️該方法會從服務例項中取出host:port來替換這個服務名。

從該介面中,我們可以通過定義的抽象方法來了解到客戶端負載均衡器中應具備的幾種能力:

▪️ServiceInstance choose(String serviceId):父介面ServiceInstanceChooser的方法,根據傳入的服務名serviceId,從負載均衡器中挑選一個對應服務的例項。

▪️ T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest request)

:使用從負載均衡器中挑選出的服務例項來執行請求內容。

▪️URI reconstructURI(ServiceInstance instance, URI original):為系統構建一個合適的host:port形式的URI。在分散式系統中,我們使用邏輯上的服務名稱作為host來構建URI(替代服務例項的host:port形式)進行請求,比如http://myservice/path/to/service。在該操作的定義中,前者ServiceInstance物件是帶有host和port的具體服務例項,而後者URI物件則是使用邏輯服務名定義為host的URI,而返回的URI內容則是通過ServiceInstance的服務例項詳情拼接host:port形式的請求地址。

  到這裡,LoadBalancerClient還只是一個抽象的負載均衡器介面,所以我們還需要找到它的具體實現類進一步進行分析,通過檢視Ribbon的原始碼,可以很容易地在org.springframework.cloud.netflix.ribbon包下找到對應的實現類RibbonLoadBalancerClient

org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient

  

此類實現了介面並作了具體邏輯處理。

然後在與LoadBalancerClient類同包下發現了自動配置類

org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration

為實現客戶端負載均衡器的自動化配置類LoadBalancerAutoConfiguration

從LoadBalancerAutoConfiguration類上的註解可知,Ribbon實現負載均衡自動化配置需要滿足下面兩個條件:

▪️@ConditionalOnClass(RestTemplate.class):RestTemplate必須存在於當前工程的環境中。

▪️@ConditionalOnBean(LoadBalancerClient.class):在Spring的Bean工程中必須有LoadBalancerClient的實現bean。

該自動配置類,主要做了下面三件事:

建立了一個LoadBalancerInterceptor的Bean,用於實現對客戶端發起請求時進行攔截,以實現客戶端負載均衡。

建立了一個RestTemplateCustomizer的Bean,用於給RestTemplate增加LoadbalancerInterceptor

維護了一個被@LoadBalanced註解修飾的RestTemplate物件列表,並在這裡進行初始化,通過呼叫RestTemplateCustomizer的例項來給需要客戶端負載均衡的RestTemplate增加LoadBalancerInterceptor攔截器。

當一個被@LoadBalanced註解修飾的RestTemplate物件向外發起HTTP請求時,會被LoadBalancerInterceptor類的intercept函式所攔截。由於我們在使用RestTemplate時候採用了服務名作為host,所以直接從HttpRequest的URI物件中通過getHost()就可以拿到服務名,然後呼叫execute函式去根據服務名來選擇例項併發起實際的請求。

負載均衡器

Ping:在BaseLoadBalancer的預設建構函式中,會直接啟動一個用於定時檢查server是否健康的任務。該任務預設的執行間隔為:10秒。

ServerList: 服務列表(總)

ServerListUpdater: 服務更新時最新到達的地方

ServerListFilter:介面非常簡單,該介面中定義了一個方法List getFilteredListOfServers(List servers),主要用於實現對服務例項列表的過濾,通過傳入的服務例項清單,根據一些規則返回過濾後的服務例項清單。

Rule --> IRule: 負載策略介面