1. 程式人生 > >spring cloud ribbon 負載均衡類1

spring cloud ribbon 負載均衡類1

size work 整合 轉換 com 負載均衡 image 處理 add

Ribbon 在實現客戶端負載均衡時,是通過Ribbo的ILoadBalancer接口實現的。

技術分享圖片

AbstractLoadBalancer

是ILoadBalancer接口的抽象實現,定義了一個分組枚舉類ServerGroup

技術分享圖片

還實現了一個chooseServer()方法,其中key為null,表示在選擇具體實例時忽略key的條件判斷

還定義了兩個抽象方法

    getServerList(ServerGroup serverGroup):根據分組類型獲取不同的實例列表

    getLoadBalancerStats():定義了獲取LoadBalancerStats對象的方法,

LoadBalancerStats對象被用來存儲負載均衡中各個服務實例當前的屬性和統計信息。

BaseLoadBalancer

是Ribbon負載均衡的基礎實現類,

  定義並維護了兩個存儲服務實例Server對象的列表。一個用於存儲所有服務實例的清單,

一個用於存儲正常服務的實例清單

技術分享圖片

  定義了各服務實例屬性和統計信息的LoadBalancerStats對象

  定義了檢查服務實例是否正常服務的IPing對象,默認為null,構造時註入

  定義了檢查服務實例操作的執行策略對象IPingStrategy,在BaseLoadBalancer中

默認使用了SerialPingStrategy,遍歷檢查

  定義了負載均衡的處理規則IRule對象,從BaseLoadBalancer中

chooseServer(Object key),實際將選擇任務委托給IRule.choose()方法,IRule默認為

RoundRobinRule

技術分享圖片

  啟動ping任務:在BaseLoadBalancer的默認構造方法中,會直接啟動一個用於定時檢查Server是否健康的任務

技術分享圖片

  DynamicServerListLoadBalancer<T>

對基礎負載均衡的擴展。在該負載均衡中,實現了服務實例清單在運行期的動態更新能力;

同時,還具備了對服務實例清單的過濾功能。新增如下

  ServerList<T> serverListImpl

技術分享圖片

ServerList繼承結構如下

技術分享圖片

上圖中有多個ServerList的實現類,那麽在DynamiceServerListLoadBalancer中的ServerList默認配置到底使用了哪個具體實現?

既然該負載均衡類中需要實現服務實例的動態更新,那麽勢必需要Ribbon具備訪問Eureka來獲取服務實例的能力,在包

org.springframework.cloud.netflix.ribbon.eureka下,可以找到配置類EurekaRibbonClientConfiguration,找到如下

技術分享圖片

這裏創建的一個DomainExtractingServerList實例,在這個類源碼中,還定義類一個ServerList list. 同時對getInitialListOfServers()

和getUpdatedListOfServers()的具體實現,其實委托給內部定義的ServerList list對象

技術分享圖片

由構造方法傳入的DiscoveryEnabledNIWSServerLIst實現的。

在DiscoveryEnableNIWSServerList中

技術分享圖片

在obtainServersViaDiscovery()方法中

技術分享圖片

技術分享圖片

主要邏輯是,依靠EurekaClient從服務註冊中心獲取到具體的服務實例InstanceInfo列表,vipAddress可以理解為邏輯上的服務名如USER-SERVICE

然後遍歷,找到UP的實例轉換成DiscoveryEnabledServer對象 ,返回

返回的結果List到了DomainExtractingServerList類中,將繼續通過setZones()方法進行處理

技術分享圖片

  ServerListUpdater

  DynamicServerListLoadBalancer類中屬性ServerListUpdater中

技術分享圖片

主要是對ServerList的更新,

技術分享圖片

而ServerListUpdater的實現類不多,如下

技術分享圖片

PollingServerListUpdater:動態服務列表更新的默認策略,也就是DynamicServerListLoadBalancer中默認實現,

它通過定時任務實現更新

 EurekaNotificationServerListUpdater 需要利用Eureka的事件監聽器來驅動服務列表的更新操作

ServerListFilter

回到updateAction.doUpdate()方法,在DynamicServerListLoadBalancer中,調用updateListOfServers()方法

技術分享圖片

調用之前提到的ServerList.getUpdatedListOfServers(),獲取到從Eureka Server中獲取服務可用實例的列表。

通過ServerListFilter filter過濾,繼承關系如下

技術分享圖片

  AbstractServerListFilter:定義類過濾時需要的一個重要對象LoadBalancerStats,該對象存儲了一些屬性和統計信息等

ZoneAffinityServerListFilter:該過濾器基於“區域感知(Zone Affinity)”的方式實現服務實例的過濾,源碼

技術分享圖片

過濾後,通過shouldEnableZoneAffinity()方法來判斷是否啟用“區域感知”功能。

技術分享圖片

使用LoadBalancerStats.getZoneSnapshot()獲取過濾後同區域實例的基礎指標(包含實例數量,斷路器斷開數,活動請求數,實例平均負載等)

根據一系列的算法求出下面的幾個評價值並與設置的閾值進行比較,若有一個條件符合,就不啟用“區域感知”。

可以實現當集群出現區域故障時,依然可以依靠其他區域的實例進行正常服務的高可用保障。

  blackOutServerPercentage:故障實例百分比(斷路器斷開數/實例數)>=0.8

activeRequestsPerServer:實例平均負載>=0.6

availableSevers: 可用實例數(實例數 - 斷路器斷開數)<2

DefaultNIWSServerListFilter 完全繼承ZoneAffinityServerListFilter,是默認NIWS(Netflix Internal Web Server)過濾器

ServerListSubSetFilter:
ZonePreferenceServerListFilter: Spring Cloud整合時新增的過濾器。若使用Spring Cloud整合Eureka和Ribbon時默認使用該過濾器

技術分享圖片

根據zone過濾出實例

spring cloud ribbon 負載均衡類1