概述
? ? 本篇文章主要是想講解清楚dubbo的負(fù)載均衡策略虱朵,其中文章的內(nèi)容部分共享自網(wǎng)絡(luò)撑帖,部分來自自己的整理,目的還是跟以往一樣黎烈,將一個簡單的問題講解清楚。
負(fù)載均衡策略及優(yōu)缺點(diǎn)
? ? Dubbo 負(fù)載均衡策略提供下列四種方式:
? ? Random LoadBalance 隨機(jī),按權(quán)重設(shè)置隨機(jī)概率照棋。 Dubbo的默認(rèn)負(fù)載均衡策略
? ? ? ? 在一個截面上碰撞的概率高资溃,但調(diào)用量越大分布越均勻,而且按概率使用權(quán)重后也比較均勻烈炭,有利于動態(tài)調(diào)整提供者權(quán)重溶锭。
? ? RoundRobin LoadBalance 輪循,按公約后的權(quán)重設(shè)置輪循比率梳庆。
? ? ? ? 存在慢的提供者累積請求問題暖途,比如:第二臺機(jī)器很慢,但沒掛膏执,當(dāng)請求調(diào)到第二臺時就卡在那驻售,久而久之,所有請求都卡在調(diào)到第二臺上更米。
? ? LeastActive LoadBalance 最少活躍調(diào)用數(shù)欺栗,相同活躍數(shù)的隨機(jī),活躍數(shù)指調(diào)用前后計數(shù)差征峦。
? ? ? ? 使慢的提供者收到更少請求迟几,因為越慢的提供者的調(diào)用前后計數(shù)差會越大。
? ? ConsistentHash LoadBalance 一致性Hash栏笆,相同參數(shù)的請求總是發(fā)到同一提供者类腮。
? ? ? ? 當(dāng)某一臺提供者掛時,原本發(fā)往該提供者的請求蛉加,基于虛擬節(jié)點(diǎn)蚜枢,平攤到其它提供者,不會引起劇烈變動针饥。
Random負(fù)載均衡策略
? ? 負(fù)載均衡策略也分為權(quán)重相同和權(quán)重不相同兩種情況進(jìn)行處理厂抽,整個代碼處理是先計算各個invoker(provider)的權(quán)重,判定權(quán)重是否相等以及總權(quán)重是多少丁眼。
? ? 如果權(quán)重不相等筷凤,那么我們就對總權(quán)重進(jìn)行隨機(jī)取值(通過random.nextInt實(shí)現(xiàn)),然后遍歷invokers將隨機(jī)的權(quán)重值減去每個invoker的權(quán)重苞七,如果得出的結(jié)果為負(fù)數(shù)說明由該invoker提供服務(wù)藐守。
? ? 如果權(quán)重相等,那么就通過random.nextInt()在所有的invoker當(dāng)中隨機(jī)選擇一個invoker就可以了蹂风。
RoundRobin負(fù)載均衡策略
? ? 輪詢負(fù)載均衡策略分為權(quán)重相同和權(quán)重不同兩種策略吗伤,整個代碼遍歷所有invoker的權(quán)重求出最小最大權(quán)重以及權(quán)重之和。
? ? 針對每個方法硫眨,我們會維持一個sequences對象,這個其實(shí)就是一個atomic類的整數(shù)類型計數(shù)。每次進(jìn)來的時候會循環(huán)遞增礁阁。
? ? 針對權(quán)重不相同的情況巧号,我們外層循環(huán)按照最大權(quán)重去循環(huán),內(nèi)層循環(huán)是invoker的個數(shù)姥闭,這里其實(shí)我們要記住由于我們總權(quán)重是把所有invoker的權(quán)重相加丹鸿,而循環(huán)是拿最大權(quán)重*所有invoker的個數(shù),所以后者肯定大于前者棚品。
? ? 權(quán)重不同的舉個例子靠欢,假設(shè)invoker A權(quán)重400,invoker B權(quán)重為100铜跑,invoker C權(quán)重為100门怪,這個時候假設(shè)mod為300,那么在遍歷A,B,C過程中我們會將mod進(jìn)行遞減锅纺,invoker A掷空、B、C遞減囤锉,最后發(fā)現(xiàn)invoker剩余300坦弟,最后返回invoker A,這里的關(guān)鍵是遞減那部分邏輯很重要官地。
? ? 針對權(quán)重相同的情況其實(shí)就是我們常見的i++%invoker個數(shù)酿傍。
LeastActive負(fù)載均衡策略
? ? 最小active的負(fù)載均衡策略也分為有權(quán)重和沒有權(quán)重兩種情況,整體思路是每次在所有invoker中獲取active最低的個數(shù)驱入,然后后面的invoker選擇就在最低active的集群當(dāng)中選擇赤炒。
? ? 有權(quán)重和沒有權(quán)重的最低active選擇都是基于上面說的數(shù)組,舉個例子沧侥,假如現(xiàn)在有4個invoker可霎,然后具備最低active的invoker有2個,那么后面我們就在最低active的2個invoker進(jìn)行選擇宴杀。
? ? 帶權(quán)重的選擇就是根據(jù)最低active的權(quán)重和隨機(jī)生成一個隨機(jī)權(quán)重癣朗,然后遍歷最低active的數(shù)目,每次減去invoker的權(quán)重旺罢,當(dāng)權(quán)重為負(fù)數(shù)的時候就以該invoker提供服務(wù)旷余。
? ? 不帶權(quán)重的選擇就是根據(jù)最低active的數(shù)量通過random.nextInt方式隨機(jī)返回一個invoker就可以。
ConsistentHash負(fù)載均衡策略
? ? 一致性hash的負(fù)載均衡策略其實(shí)就跟一致性hash的原理一樣扁达,主要也是分成生成虛擬節(jié)點(diǎn)和選擇節(jié)點(diǎn)提供服務(wù)正卧。
? ? 首先我們先生成invoker也就是服務(wù)接口對應(yīng)的selector,原則是沒有就生成一個跪解。每個invoker虛擬節(jié)點(diǎn)的生成的原則很簡單:會根據(jù)虛擬節(jié)點(diǎn)設(shè)置的個數(shù)/4進(jìn)行外層循環(huán)炉旷,以4進(jìn)行內(nèi)層循環(huán)生成。
? ? 其次我們提取請求中攜帶的參數(shù)(因為我們規(guī)定了按照哪些參數(shù)進(jìn)行hash)生成hash值,然后選擇對應(yīng)的虛擬節(jié)點(diǎn)(如果存在這個hash值)窘行,或者選擇大于該值的第一個虛擬節(jié)點(diǎn)的值饥追,最后去選擇對應(yīng)的invoker。
負(fù)載均衡之源碼debug
? ? 1罐盔、先本地啟動zookeeper的注冊中心? ?
? ? 2但绕、直接復(fù)用dubbo的源碼,我們需要修改provider里面的properties然后啟動多個provider惶看,只有多個provider才能調(diào)試負(fù)載均衡策略捏顺。
? ? 3、consumer直接進(jìn)行debug跟蹤即可纬黎。