當前位置:
首頁 > 最新 > Spring Cloud中負載均衡器概覽

Spring Cloud中負載均衡器概覽

在上篇文章中(RestTemplate的逆襲之路,從發送請求到負載均衡)我們完整的分析了RestTemplate的工作過程,在分析的過程中,我們遇到過一個ILoadBalancer介面,這個介面中有一個chooseServer方法是我們選擇服務實例的方法,這個也是整個負載均衡中最最核心的部分,那麼它到底是採用了什麼樣的策略從服務提供者列表中選出了一個服務供服務消費者去調用的?這是我們今天要討論的問題,本文我主要是想基於互聯網上公開的資料,來對Spring Cloud中提供的負載均衡器做一個簡明扼要的介紹。

本文是Spring Cloud系列的第八篇文章,了解前七篇文章內容有助於更好的理解本文:

負載均衡器

首先我們來看一張上篇文章中的舊圖:

這是ILoadBalancer介面的一張類關係圖,我們就從這張圖裡看起吧。

AbstractLoadBalancer

AbstractLoadBalancer類的定義如下:

關於這個類我說以下幾點:

1.AbstractLoadBalancer實現了ILoadBalancer介面,但它是一個抽象類,它裡邊定義了一個關於服務實例的分組枚舉類,包含了三種類型的服務:表示所有服務,表示正常運行的服務,表示下線的服務。

2.chooseServer方法毫無疑問是用來選取一個服務實例,但是要怎麼選這裡並沒有說,我們以後在它的實現類裡邊尋找選取策略。

3.getServerList方法用來獲取某一個分組中所有的的服務實例。

4.getLoadBalancerStats方法用來獲取LoadBalancerStats對象,LoadBalancerStats對象中保存了每一個服務的所有細節信息。

BaseLoadBalancer

BaseLoadBalancer是AbstractLoadBalancer的一個實現類,源碼比較長我就不貼出來的,我們在這裡主要來說說BaseLoadBalancer提供了哪些功能:

1.首先這個類中有兩個List集合中放的Server對象,一個List集合用來保存所有的服務實例,還有一個List集合用來保存當前有效的服務實例。

2.BaseLoadBalancer中定義了一個IPingStrategy,用來描述服務檢查策略,IPingStrategy默認實現採用了SerialPingStrategy實現,SerialPingStrategy中的pingServers方法就是遍歷所有的服務實例,一個一個發送請求,查看這些服務實例是否還有效,如果網路環境不好的話,這種檢查策略效率會很低,如果我們想自定義檢查策略的話,可以重寫SerialPingStrategy的pingServers方法。

3.在BaseLoadBalancer的chooseServer方法中(負載均衡的核心方法),我們發現最終調用了IRule中的choose方法來找到一個具體的服務實例,IRule是一個介面,在BaseLoadBalancer它的默認實現是RoundRobinRule類,RoundRobinRule類中採用了最常用的線性負載均衡規則,也就是所有有效的服務端輪流調用。

4.在BaseLoadBalancer的構造方法中會啟動一個PingTask,這個PingTask用來檢查Server是否有效,PingTask的默認執行時間間隔為10秒。

5.markServerDown方法用來標記一個服務是否有效,標記方式為調用Server對象的setAlive方法設置isAliveFlag屬性為false。

6.getReachableServers方法用來獲取所有有效的服務實例列表。

7.getAllServers方法用來獲取所有服務的實例列表。

8.addServers方法表示向負載均衡器中添加一個新的服務實例列表。

BaseLoadBalancer的功能大概就這麼多。

DynamicServerListLoadBalancer

DynamicServerListLoadBalancer是BaseLoadBalancer的一個子類,在DynamicServerListLoadBalancer中對基礎負載均衡器的功能做了進一步的擴展,我們來看看。

1.首先DynamicServerListLoadBalancer類一開始就聲明了一個變數serverListImpl,serverListImpl變數的類型是一個,這裡的泛型得是Server的子類,ServerList是一個介面,裡邊定義了兩個方法:一個getInitialListOfServers用來獲取初始化的服務實例清單;另一個getUpdatedListOfServers用於獲取更新的服務實例清單。

2.ServerList介面有很多實現類,DynamicServerListLoadBalancer默認使用了DomainExtractingServerList類作為ServerList的實現,但是在DomainExtractingServerList的構造方法中又傳入了DiscoveryEnabledNIWSServerList對象,查看源碼發現最終兩個清單的獲取方式是由DiscoveryEnabledNIWSServerList類來提供的。

3.DomainExtractingServerList類中的obtainServersViaDiscovery方法是用來發現服務實例並獲取的,obtainServersViaDiscovery方法的主要邏輯是這樣:首先依靠EurekaClient從服務註冊中心獲取到具體的服務實例InstanceInfo列表,然後對這個列表進行遍歷,將狀態為UP的實例轉換成DiscoveryEnabledServer對象並放到一個集合中,最後將這個集合返回。

4.DynamicServerListLoadBalancer中還定義了一個ServerListUpdater.UpdateAction類型的服務更新器,Spring Cloud提供了兩種服務更新策略:一種是PollingServerListUpdater,表示定時更新;另一種是EurekaNotificationServerListUpdater表示由Eureka的事件監聽來驅動服務列表的更新操作,默認的實現策略是第一種,即定時更新,定時的方式很簡單,創建Runnable,調用DynamicServerListLoadBalancer中updateAction對象的doUpdate方法,Runnable延遲啟動時間為1秒,重複周期為30秒。

5.在更新服務清單的時候,調用了我們在第一點提到的getUpdatedListOfServers方法,拿到實例清單之後,又調用了一個過濾器中的方法進行過濾。過濾器的類型有好幾種,默認是DefaultNIWSServerListFilter,這是一個繼承自ZoneAffinityServerListFilter的過濾器,具有區域感知功能。即它會對服務提供者所處的Zone和服務消費者所處的Zone進行比較,過濾掉哪些不是同一個區域的實例。

綜上,DynamicServerListLoadBalancer主要是實現了服務實例清單在運行期間的動態更新能力,同時提供了對服務實例清單的過濾功能。

ZoneAwareLoadBalancer

ZoneAwareLoadBalancer是DynamicServerListLoadBalancer的子類,ZoneAwareLoadBalancer的出現主要是為了彌補DynamicServerListLoadBalancer的不足。由於DynamicServerListLoadBalancer中並沒有重寫chooseServer方法,所以DynamicServerListLoadBalancer中負責均衡的策略依然是我們在BaseLoadBalancer中分析出來的線性輪詢策略,這種策略不具備區域感知功能,這樣當需要跨區域調用時,可能會產生高延遲。ZoneAwareLoadBalancer重寫了setServerListForZones方法,該方法在其父類中的功能主要是根據區域Zone分組的實例列表,為負載均衡器中的LoadBalancerStats對象創建ZoneStats並存入集合中,ZoneStats是一個用來存儲每個Zone的狀態和統計信息。重寫之後的setServerListForZones方法主要做了兩件事:一件是調用getLoadBalancer方法來創建負載均衡器,同時創建服務選擇策略;另一件是對Zone區域中的實例清單進行檢查,如果對應的Zone下已經沒有實例了,則將Zone區域的實例列表清空,防止節點選擇時出現異常。

OK,以上就是我們對負載均衡器的一個簡單介紹,下一篇文章我們將繼續介紹負載均衡策略

以上。。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 玩轉JavaEE 的精彩文章:

TAG:玩轉JavaEE |