負載均衡
叢集負載平衡時,Dubbo 提供了多種平衡策略,預設為 random
隨機呼叫。
具體實現上,Dubbo 提供了客戶端負載平衡,即 Consumer 端使用負載平衡演算法決定將請求提交到哪個 Provider 实例。
您可以自行擴展負載平衡策略,請參閱:負載平衡擴展
負載平衡策略
目前 Dubbo 擁有以下內建負載平衡演算法,用戶可以直接配置使用
| 演算法 | 特性 | 備註 | | :————————– | :——————– – | :———————————————- | | RandomLoadBalance | 加權隨機 | 預設演算法,預設權重相同 | | RoundRobinLoadBalance | 加權輪詢 | 基於 Nginx 的平滑加權輪詢演算法,預設權重相同, | | LeastActiveLoadBalance | 最少活躍優先 + 加權隨機 | 背後是能者多勞的思想 | | ShortestResponseLoadBalance | 最快回應優先 + 加權隨機 | 更關注回應速度 | | ConsistentHashLoadBalance | 一致性雜湊 | 確定的輸入參數,確定的 Provider,適用於有狀態請求 |
隨機
- 加權隨機,按權重設定隨機機率。
- 一段時間內碰撞的機率高,但呼叫量越大分佈越均勻,而且按機率使用後也比較符合權重設定,有利於動態調整 Provider 權重。
- 缺點:存在慢的 Provider 累積請求的問題。舉例說明:第二台機器很慢,但沒掛,當請求調到第二台時就卡在那,久而久之,所有請求都卡在第二台上。
輪詢
- 加權輪詢,根據約定後的權重設置輪詢比率,然後循環調用節點
- 缺點:也存在請求堆積到慢提供者上的問題。
加權輪詢過程中,如果某個節點的權重過大,會出現一段時間內調用過於集中的問題。比如ABC三個節點有如下權重:{A: 3, B: 2, C: 1}
那麼按照最原始的輪詢算法,調用過程將變成:A A A B B C
對此,Dubbo參考了Nginx的平滑加權輪詢算法進行了優化。 調用過程可以抽象成下表
| 輪詢前總權重 | 本輪勝出者 | 總權重 | 輪詢後權重(勝出者減總權重) | | :—————— | :——- | :——- | :———- —————– | | 起始輪 | \ | \ | A(0), B(0), C(0)
| | A(3), B(2), C(1)
| A | 6 | A(-3), B(2), C(1)
| | A(0), B(4), C(2)
| B | 6 | A(0), B(-2), C(2)
| | A(3), B(0), C(3)
| A | 6 | A(-3), B(0), C(3)
| | A(0), B(2), C(4)
| C | 6 | A(0), B(2), C(-2)
| | A(3), B(4), C(-1)
| B | 6 | A(3), B(-2), C(-1)
| | A(6), B(0), C(0)
| A | 6 | A(0), B(0), C(0)
|
我們發現,經過總權重 (3+2+1) 輪後,又回到了起點,整個過程節點流量平滑,並且在一段時間內,其概率也符合預期分佈。
如果用戶有加權輪詢的需求,可以放心使用該算法。
最不活躍優先
- 加權最不活躍優先調用,活躍數越小,優先級越高,相同活躍數則隨機加權。活躍數指調用前後計數差(針對特定提供者:發送請求數 - 接收響應數),表示服務提供者的一個負載度,活躍數越小,說明服務提供者處理能力越強。
- 使慢的提供者收到更少請求,因為越慢的提供者,調用前後計數差越大;相對的,處理能力更強的節點可以處理更多請求。
###最短響應時間優先
- 加權最短響應時間優先調用,在最新滑動窗口內,響應時間越短,優先級越高,相同響應時間則隨機加權。
- 使響應時間更快的提供者處理更多請求。
- 缺點:可能會導致流量過於集中到高性能節點上。
這裡的響應時間 = 某個提供者在窗口時間內的平均響應時間,默認窗口時間為 30s。
###一致性 Hash
- 一致性 Hash,相同參數的請求永遠發送到同一個提供者。
- 當某台提供者掛掉時,原本發往該提供者的請求,基於虛擬節點,會分散到其他提供者,不會引起劇烈變動。
- 算法請參考:一致性雜湊 | 維基百科
- 默認只對第一個參數 Hash,如果要修改,請配置
<dubbo:parameter key="hash.arguments" value="0,1" />
- 默認使用 160 個虛擬節點,如果要修改,請配置
<dubbo:parameter key="hash.nodes" value="320" />
配置
服務端服務級別
<dubbo:service interface="..." loadbalance="roundrobin" />
客戶端服務級別
<dubbo:reference interface="..." loadbalance="roundrobin" />
服務端方法級別
<dubbo:service interface="...">
<dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:service>
客戶端方法級別
<dubbo:reference interface="...">
<dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:reference>