Spring cloud客戶端負載均衡與ribbon的設計思路

weixin_34321977發表於2017-10-09

在看網文或《spring cloud微服務實戰》(以下簡稱:實戰)時,發覺對spring cloud Netflix ribbon的描述容易陷入細節,初學者看的暈乎。本人重新看了實戰、網文和spring cloud ribbon相關程式碼,終於理清其思路,隨寫下備忘筆記。

《金字塔原理》說要表達一個事情,結論先行是最好的方式。因此理解spring cloud Netflix ribbon原始碼,最好是先理解它設計初衷(思考:假設是自己設計,會怎麼做)。 

spring cloud Netflix ribbon作用是利用Netflix的ribbon元件實現客戶端負載均衡(以下簡稱:CLB),即 = Spring cloud + ribbon。作為Spring cloud的設計者,顯然不想緊耦合ribbon;反之亦然。而網友把Spring cloud和ribbon揉在一起描述,是讓人暈乎的原因

很自然的,假設我們設計Spring cloud的CLB 和 ribbon,頂層思路是要考慮這幾個事情:

1. 設計spring cloud自己的通用CLB介面,用於呼叫第三方的CLB元件

2. 設計ribbon(第三方的CLB元件)介面:定義作為客戶端負載均衡器應有的operations

3. 利用介面卡,裝飾器(或wrapper)之類的模式將spring cloud與ribbon對接起來。

4. 在服務間通訊的元件(如:Resttemplate)中,放入CLB的呼叫

OK,開始幹活。

1. 我們設計名為LoadBalancerClient的介面,作為Spring cloud CLB通用介面類,裡面應該有這樣的介面函式:接收請求,並從服務例項列表挑選一個作為請求接收方;

2.  設計ribbon介面類:ILoadBalancer, 一個最簡單的LB的至少有點功能:設定新增和讀取後端的服務(器)列表;能從中選擇一個服務(器)

3. 同時提供一個LoadBalancerClient實現類將上面的兩者整合適配:RibbonLoadBalancerClient.

6418493-908ad861f470ab8e.png
圖1

4. 用耦合度最低的方式:往客戶端發起請求的地方(Resttemplate)增加一個攔截器,攔截器中呼叫LoadBalancerClient的bean(RibbonLoadBalancerClient)實現CLB功能。增加攔截器這個動作,最好能自動完成,熟悉Spring boot的同學會很快想到,用autoconfig(LoadBalancerAutoConfiguration):

6418493-65d9ab584a45d5a4.png
圖2

上面是設計者的頂層設計,接下來要對每個介面的實現進行設計(很像金字塔原理)。

Cloud側介面LoadBalancerClient的設計:參看原始碼或《實戰》、網文

Cloud側RibbonLoadBalancerClient:既然是適配、包裝,則免不了1)呼叫ribbon的服務例項選擇介面(chooseServer),2)然後包裝一下返回的的服務例項(用RibbonServer),用於儲存url,port之外的HTTPS,後設資料等資訊 3)根據例項資訊重構具體請求要送達的url(reconstructURI) 4)同時在做些統計之類的事情(用RibbonStatsRecorder工具,ribbon已經做了統計,這裡為何要統計?我沒搞清楚

Cloud側LoadBalancerInterceptor:參考原始碼或《實戰》

ribbon側ILoadBalancer等詳細設計:CLB的具體實現邏輯都在這裡,因此好好斟酌一下,如果是我們設計,應該包含哪些特性:

1)維護一個server(服務提供方)的列表:server list,獲取方式可配

2)可動態更新server list,更新策略可配

3)可監測server list的可用性:監測方法可配

4)可配置多個負載均衡策略

5)可過濾部分servers:過濾規則也是可配

根據所想要的特想, 不難設計如下類圖(暫時先不用看介面實現):


6418493-3285b9cffb894e99.png
圖3

IClientConfig,IRule,IPing,ServerLis,ServerListFilter,ServerListUpdater幾個介面分別實現了上述設計特性。最基礎的實現類是BaseLoadBalancer,DynamicServerListLoadBalancer和ZoneAwareLoadBalancer(上圖未列出)只是擴充套件了他的功能。

未完待續...後續將寫上更詳細的原始碼閱讀隨筆和基於ribbon的自定義灰度釋出功能實現

相關文章