Dubbo篇 負載均衡策略原始碼分析

2021-10-08 20:50:07 字數 2782 閱讀 4222

在進行消費端服務呼叫的時候,看到初始化了loadbalance,通過負載均衡獲取乙個可用的節點。loadbalance也是乙個擴充套件點,dubbo內建了4種負載均衡演算法,

都繼承自abstractloadbalance,abstractloadbalance中實現通用邏輯,留乙個抽象方法doselect方法給子類實現,預設是randomloadbalance實現。四個負載均衡實現子類如下:

randomloadbalance:隨機,按權重設定隨機概率。在乙個截面上碰撞的概率高,但呼叫量越大分布越均勻,而且按概率使用權重後也比較均勻,有利於動態調整提供者的權重。

roundrobinloadbalance:輪詢,按公約後的權重設定輪詢比例。存在慢的提供者累計請求的問題,比如:第二天機器很慢,但沒「掛」,當請求調到第二台時就卡在那裡,久而久之,所以請求都卡在調到第二台上。

leastactiveloadbalance:最少活躍呼叫數,如果活躍數相同則隨機呼叫,活躍數指呼叫前後計數差。使慢的提供者收到更少請求,因為越慢的提供者的呼叫前後計數差會越大。

consistenthashloadbalance:一致性hash,相同引數的請求總是發到同一提供者。當某一台提供者「掛」是,原本發往該提供者的請求,基於虛擬節點,會平攤到其他提供者,不會引起劇烈變動。預設只對第乙個引數「hash」,預設使用160份虛擬節點。

abstractloadbalance實現較為簡單,提供了乙個select方法呼叫子類重寫的doselect方法,提供了getweight用於計算權重,**實現如下:

getweight獲取當前權重,其中呼叫了calculatewarmupweight,主要實現了獲取權重的時的預熱,服務啟動是並不會直接給予100%的流量,計算邏輯是:(啟動至今時間 / 給予的預熱總時間)* 權重。

randomloadbalance按照權重設定隨機概率做負載均衡,這種演算法並不能精確地做平均請求,但是隨著請求數量的增加,最終結果大致平均,**實現如下:

時間比較簡單,如果權重都一樣,則直接隨機返回乙個,如果權重不一樣,則把每個invoker的權重看作乙個區間,以總權重為基礎獲取乙個隨機數,然後用隨機數依次減去每個權重,當隨機數小於零的時候結束,即看這個隨機數落在哪個invoker的權重區間中,就返回這個invoker。

roundrobin負載均衡演算法的實現為平滑權重輪詢演算法。在輪詢的基礎上加上了負載均衡的演算法。實現**如下:

演算法邏輯是每次請求做負載均衡時,會遍歷所有invoker節點,對於每個invoker,會讓它的current = current + weight。同時會把每個invoker的weight累加到totalweight總權重,即totalweight = totalweight + weight。遍歷完成後會儲存current值最大的就是本次要返回的節點,返回前會將其current減去totalweight,即current = current - totalweight,現在選擇的時候會在現有的current值上基礎上再做上次操作,將totalweight置0,重複上述邏輯。選中過的invoker的current值會因為減去了totalweight,所以最小,再次選中它的話就要等根據自身權重一次一次加成最大,因此權重大的就更快的再次被選中,權重小的就慢些被再次被選中,而且不也會一直呼叫權重大的invoker,會有權重小的穿插進去。

leastactive負載均衡是最小活躍呼叫數負載均衡,框架會記下每個invoker的活躍數,每次只從活躍數最小的invoker裡選乙個節點。這個負載均衡演算法需要配合activelimitfilter過濾器來計算每個介面方法的活躍數。leastactiveloadbalance**實現如下:

其實現邏輯較為簡單,遍歷invoker列表,找出其所有活躍數最小的invoker,儲存到乙個集合中,然後用random負載均衡方式從中選出乙個invoker。

一致性hash負載均衡可以讓引數相同的請求每次都路由到相同的機器上。這種負載均衡的方式可以然後請求相對平均,當某些節點下線時,請求會平攤到其他服務者,不會引起劇烈的變動。dubbo框架使用了優化過ketama一致性hash,這種演算法會為每個節點在建立多個虛擬節點,讓節點在環形上的分布更均勻,後續的呼叫也會隨之更加均勻。consistenthashloadbalance**實現如下:

邏輯核心在consistenthashselector中,consistenthashselector初始化時會對節點進行雜湊,雜湊的環形使用乙個treemap實現,所有的真實、虛擬的節點都會放入treemap。把節點的ip+遞增數字做「md5」,以此作為節點標識,再對標識做hash得到treemap的key,最後把可以呼叫的節點作為treemap的value。在客戶端呼叫的時候,只要對請求的引數也做md5即可,雖然此時得到的md5之不一定能對應到treemap的key,因為每次請求的引數不一樣,以為treemap是有序樹形結構,可以呼叫treemap的ceilingentry方法,用於返回乙個至少大於或等於當前給定key的entry,從而達到順時針往前找的效果。如果找不到,則使用firstentry返回第乙個節點。

參考:《深入理解 apache dubbo與實戰》

Dubbo 負載均衡策略

隨機 random loadbalance 隨機,按權重設定隨機概率。在乙個截面上碰撞的概率高,但呼叫量越大分布越均勻,而且按概率使用權重後也比較均勻,有利於動態調整提供者權重。權重可以在 dubbo 管控臺配置 輪循 roundrobin loadbalance 輪循,按公約後的權重設定輪循比率。...

dubbo自定義負載均衡策略及相關原始碼解析

最近在研究即時訊息推送系統 im系統 的架構,自己用netty開發了基礎網路通訊部分,用來維護tcp連線,在客戶端上線時將使用者標識userid和路由資訊存在redis中,通過dubbo向上層模組提供訊息推送介面。在上層訊息 路由模組設計時,遇到了乙個問題,dubbo介面呼叫時要根據路由資訊中的ip...

Dubbo的負載均衡策略

配置方式 負載均衡改善了跨多個計算資源 例如計算機,計算機集群,網路鏈結,處理單元或磁碟驅動的的工作負載分布。負載均衡旨在優化資源使用,最大化吞吐量,最小化響應時間,並避免任何單個資源的過載。使用具有負載平衡而不是單個元件。多個元件可以通過冗餘提高可靠性和可用性。負載平衡通常涉及專用軟體或硬體。比如...