spring cloud ribbon 負(fù)載均衡類

Ribbon 在實(shí)現(xiàn)客戶端負(fù)載均衡時母债,是通過Ribbo的ILoadBalancer接口實(shí)現(xiàn)的。

AbstractLoadBalancer

是ILoadBalancer接口的抽象實(shí)現(xiàn),定義了一個分組枚舉類ServerGroup

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

還定義了兩個抽象方法

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

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

LoadBalancerStats對象被用來存儲負(fù)載均衡中各個服務(wù)實(shí)例當(dāng)前的屬性和統(tǒng)計(jì)信息更胖。

BaseLoadBalancer

是Ribbon負(fù)載均衡的基礎(chǔ)實(shí)現(xiàn)類,

  定義并維護(hù)了兩個存儲服務(wù)實(shí)例Server對象的列表隔显。一個用于存儲所有服務(wù)實(shí)例的清單却妨,

一個用于存儲正常服務(wù)的實(shí)例清單

  定義了各服務(wù)實(shí)例屬性和統(tǒng)計(jì)信息的LoadBalancerStats對象

  定義了檢查服務(wù)實(shí)例是否正常服務(wù)的IPing對象,默認(rèn)為null括眠,構(gòu)造時注入

  定義了檢查服務(wù)實(shí)例操作的執(zhí)行策略對象IPingStrategy彪标,在BaseLoadBalancer中

默認(rèn)使用了SerialPingStrategy,遍歷檢查

  定義了負(fù)載均衡的處理規(guī)則IRule對象掷豺,從BaseLoadBalancer中

chooseServer(Object key)捞烟,實(shí)際將選擇任務(wù)委托給IRule.choose()方法,IRule默認(rèn)為

RoundRobinRule

  啟動ping任務(wù):在BaseLoadBalancer的默認(rèn)構(gòu)造方法中当船,會直接啟動一個用于定時檢查Server是否健康的任務(wù)

  DynamicServerListLoadBalancer

????? 對基礎(chǔ)負(fù)載均衡的擴(kuò)展题画。在該負(fù)載均衡中,實(shí)現(xiàn)了服務(wù)實(shí)例清單在運(yùn)行期的動態(tài)更新能力德频;

同時苍息,還具備了對服務(wù)實(shí)例清單的過濾功能。新增如下

  ServerList serverListImpl

ServerList繼承結(jié)構(gòu)如下

上圖中有多個ServerList的實(shí)現(xiàn)類壹置,那么在DynamiceServerListLoadBalancer中的ServerList默認(rèn)配置到底使用了哪個具體實(shí)現(xiàn)竞思?

既然該負(fù)載均衡類中需要實(shí)現(xiàn)服務(wù)實(shí)例的動態(tài)更新,那么勢必需要Ribbon具備訪問Eureka來獲取服務(wù)實(shí)例的能力钞护,在包

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

這里創(chuàng)建的一個DomainExtractingServerList實(shí)例难咕,在這個類源碼中课梳,還定義類一個ServerList list. 同時對getInitialListOfServers()

和getUpdatedListOfServers()的具體實(shí)現(xiàn),其實(shí)委托給內(nèi)部定義的ServerList list對象

由構(gòu)造方法傳入的DiscoveryEnabledNIWSServerLIst實(shí)現(xiàn)的余佃。

在DiscoveryEnableNIWSServerList中

在obtainServersViaDiscovery()方法中

主要邏輯是惦界,依靠EurekaClient從服務(wù)注冊中心獲取到具體的服務(wù)實(shí)例InstanceInfo列表,vipAddress可以理解為邏輯上的服務(wù)名如USER-SERVICE

然后遍歷咙冗,找到UP的實(shí)例轉(zhuǎn)換成DiscoveryEnabledServer對象 沾歪,返回


返回的結(jié)果List到了DomainExtractingServerList類中,將繼續(xù)通過setZones()方法進(jìn)行處理


ServerListUpdater

  DynamicServerListLoadBalancer類中屬性ServerListUpdater中

主要是對ServerList的更新雾消,

而ServerListUpdater的實(shí)現(xiàn)類不多灾搏,如下

?? PollingServerListUpdater:動態(tài)服務(wù)列表更新的默認(rèn)策略挫望,也就是DynamicServerListLoadBalancer中默認(rèn)實(shí)現(xiàn),

它通過定時任務(wù)實(shí)現(xiàn)更新

 EurekaNotificationServerListUpdater 需要利用Eureka的事件監(jiān)聽器來驅(qū)動服務(wù)列表的更新操作


ServerListFilter

回到updateAction.doUpdate()方法狂窑,在DynamicServerListLoadBalancer中媳板,調(diào)用updateListOfServers()方法

調(diào)用之前提到的ServerList.getUpdatedListOfServers(),獲取到從Eureka Server中獲取服務(wù)可用實(shí)例的列表泉哈。

通過ServerListFilter filter過濾蛉幸,繼承關(guān)系如下

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

?????? ZoneAffinityServerListFilter:該過濾器基于“區(qū)域感知(Zone Affinity)”的方式實(shí)現(xiàn)服務(wù)實(shí)例的過濾丛晦,源碼

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

使用LoadBalancerStats.getZoneSnapshot()獲取過濾后同區(qū)域?qū)嵗幕A(chǔ)指標(biāo)(包含實(shí)例數(shù)量烫沙,斷路器斷開數(shù)匹层,活動請求數(shù),實(shí)例平均負(fù)載等)

根據(jù)一系列的算法求出下面的幾個評價值并與設(shè)置的閾值進(jìn)行比較锌蓄,若有一個條件符合升筏,就不啟用“區(qū)域感知”。

可以實(shí)現(xiàn)當(dāng)集群出現(xiàn)區(qū)域故障時瘸爽,依然可以依靠其他區(qū)域的實(shí)例進(jìn)行正常服務(wù)的高可用保障您访。

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

?????? activeRequestsPerServer:實(shí)例平均負(fù)載>=0.6

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


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

ServerListSubSetFilter:

ZonePreferenceServerListFilter: Spring Cloud整合時新增的過濾器剪决。若使用Spring Cloud整合Eureka和Ribbon時默認(rèn)使用該過濾器

根據(jù)zone過濾出實(shí)例


ZoneAwareLoadBalancer

?是對DynamicServerListLoadBalancer的擴(kuò)展洋只。DynamicServerListLoadBalancer中,沒重寫chooseServer()方法昼捍,所有它

依舊采用BaseLoadBalancer中的算法识虚。使用RoundRobinRule規(guī)則,以線性輪詢的方式來選擇調(diào)用的服務(wù)實(shí)例妒茬,該算法實(shí)現(xiàn)

簡單并沒有區(qū)域(Zone)的概念担锤,所以它會把所有實(shí)例視為一個Zone下的節(jié)點(diǎn)來看待,這樣就會周期性地產(chǎn)生跨區(qū)域(Zone)

訪問的情況乍钻,由于跨區(qū)域會產(chǎn)生更高的延遲肛循,這些實(shí)例主要以防止區(qū)域性故障實(shí)現(xiàn)高可用為目的而不能作為常規(guī)訪問的實(shí)例,

所以在多區(qū)域部署的情況下會有一定的性能問題银择,而該負(fù)載均衡則可以避免這樣的問題多糠。



在ZoneAwareLoadBalancer中,它沒有重寫setServersList浩考,說明實(shí)現(xiàn)服務(wù)實(shí)例清單的更新主邏輯沒有修改夹孔。但是發(fā)現(xiàn)它重寫了setServerListForZones(Map

List>zoneServersMap)。

在DynamicServerListLoadBalancer中查找這個方法

setServerListForZones()在

setServersList()方法的最后被調(diào)用,在父類DynamicServerListLoadBalancer中的作用是根據(jù)按區(qū)域Zone分組的實(shí)例列表搭伤,為LoadBalancerStats對象創(chuàng)建ZoneStats并放入Map

zoneStatsMap中只怎,每一個Zone對應(yīng)一個

ZoneStats,它用于存儲每個Zone的一些狀態(tài)和統(tǒng)計(jì)信息。

?? 在ZoneAwareLoadBalancer中setServerListForZones()如下

?可以看到怜俐,在該實(shí)現(xiàn)中創(chuàng)建了一個ConcurentHashMap()類型的balancers對象身堡,它將用來存儲每個Zone區(qū)域?qū)?yīng)的負(fù)載均衡器。

?其中g(shù)etLoadBalancer創(chuàng)建如下

?在創(chuàng)建負(fù)載均衡器的時候會創(chuàng)建它的規(guī)則(如果當(dāng)前實(shí)現(xiàn)中沒有IRule實(shí)例拍鲤,就創(chuàng)建一個AvailablityFilteringRule:否則克绿选)

創(chuàng)建完負(fù)載均衡器后有調(diào)用setServersList()為其設(shè)置對應(yīng)Zone區(qū)域的實(shí)例清單。

?? 第二個循環(huán)則對Zone區(qū)域中實(shí)例清單的檢查季稳,看看是否有Zone區(qū)域下已經(jīng)沒有實(shí)例了

現(xiàn)在看一下ZoneAwareLoadBalancer中chooseServer()方法

當(dāng)zone區(qū)域大于1時

?? ①調(diào)用ZoneAvoidanceRule中的靜態(tài)方法createSnapshot(lbStats)擅这,為當(dāng)前負(fù)載均衡器中所有的Zone區(qū)域創(chuàng)建快照,

保存在Map zoneSnapshot中


②調(diào)用ZoneAvoidancerRule中ZoneAvoidanceRule.getAvailableZones(zoneSnapshot,

triggeringLoad.get(), triggeringBlackoutPercentage.get());

來獲取可用的Zone區(qū)域集合绞幌,通過Zone區(qū)域快照中的統(tǒng)計(jì)數(shù)據(jù)來實(shí)現(xiàn)可用區(qū)

的挑選。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末一忱,一起剝皮案震驚了整個濱河市莲蜘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌帘营,老刑警劉巖票渠,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異芬迄,居然都是意外死亡问顷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門禀梳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杜窄,“玉大人,你說我怎么就攤上這事算途∪” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵嘴瓤,是天一觀的道長扫外。 經(jīng)常有香客問我,道長廓脆,這世上最難降的妖魔是什么筛谚? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮停忿,結(jié)果婚禮上驾讲,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好蝎毡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布厚柳。 她就那樣靜靜地躺著,像睡著了一般沐兵。 火紅的嫁衣襯著肌膚如雪别垮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天扎谎,我揣著相機(jī)與錄音碳想,去河邊找鬼。 笑死毁靶,一個胖子當(dāng)著我的面吹牛胧奔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播预吆,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼龙填,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拐叉?” 一聲冷哼從身側(cè)響起岩遗,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凤瘦,沒想到半個月后宿礁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔬芥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年梆靖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笔诵。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡返吻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乎婿,到底是詐尸還是另有隱情思喊,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布次酌,位于F島的核電站恨课,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏岳服。R本人自食惡果不足惜剂公,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吊宋。 院中可真熱鬧纲辽,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吊档,卻和暖如春篙议,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怠硼。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工鬼贱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人香璃。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓这难,卻偏偏與公主長得像,于是被迫代替她去往敵國和親葡秒。 傳聞我的和親對象是個殘疾皇子姻乓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容