一、簡介
爲什麼一開始就需要了解這一塊,原因就是這塊涉及到的組件的調用關係相對獨立,更容易理解,而這塊也是ribbon的核心之一。
二、接口
ribbon的負載均衡最終都委託給了一個類來實現,那就是IRule,IRule負責不同的策略算法,接口定義如下:
public interface IRule{
public Server choose(Object key);
public void setLoadBalancer(ILoadBalancer lb);
public ILoadBalancer getLoadBalancer();
}
通過接口定義可見,IRule需要依賴一個ILoadBalancer,這裏我們先暫時拋開不看何謂ILoadBalancer。
只看其核心的方法是Server choose(Object key),即根據key返回Server對象,而Server包含了關鍵信息,例如host,port等:
而這裏IRule僅僅是個接口,netflix提供了好多實現策略,詳細如下:
三、深入
通過上面的結構,可以瞭解到如此多的實現,這裏只拿出一個來看看其實現,別的只做描述。這裏拿比較簡單的RoundRobinRule來說明:
其邏輯比較簡單,與其他交互的組件就是從ILoadBalancer獲取server列表,之後獲取下一個下標,返回server,循環10次。
另外,它並沒有使用到傳入的參數key。
四、總結
下面將不同的策略實現做簡單的總結:
序號 | 類型 | 策略名 | 描述 | 實現簡單介紹 |
---|---|---|---|---|
1 | 不依賴於server運行狀況 | RoundRobinRule | 字如其名,輪詢獲取server | 內置計數器,計數器遞增與server列表長度取模,作爲下標來從server列表獲取下一個server |
2 | RandomRule | 字如其名,隨機獲取server | 內置jdk的Random,隨機一個小於server列表長度的數,作爲下標從server列表來獲取下一個server | |
3 | RetryRule | 在默認500ms內,通過重試獲取到可用server | 內部採用RoundRobinRule獲取server,如果server不可用,則循環重試獲取。監控線程會定時中斷重試任務。 | |
4 | ClientConfigEnabledRoundRobinRule | 輪詢選擇server | 內部依賴RoundRobinRule實現輪詢 | |
5 | 依賴於server運行狀況 | WeightedResponseTimeRule | 根據server響應時間來分配權重,響應時間越小,權重越高,選中的機率越大 | 每30s執行一次權重計算任務。權重計算以響應時間爲依據,響應時間來自於LoadBalancerStats,其中存儲了每個server的平均響應時間。權重算法類似如下: |
6 | BestAvailableRule | 獲取併發請求數最小的非故障server | 內部依賴LoadBalancerStats來判斷server是否故障(斷路器打開),同樣,從LoadBalancerStats獲取當前請求數最小的server | |
7 | AvailabilityFilteringRule | 隨機獲取可用的並且併發數小的server | 內部委託了AvailabilityPredicate來實現,依賴LoadBalancerStats來判斷server是否故障(斷路器打開),同樣,從LoadBalancerStats獲取當前請求數從而過濾掉併發量大的server | |
8 | ZoneAvoidanceRule | 排除不可用區域和性能差的區域,並選擇可用的併發數小的server。 | 與AvailabilityFilteringRule類似其內部同樣依賴了AvailabilityPredicate來實現server的判斷。 對於zone的判斷,依賴ZoneAvoidancePredicate來實現。 |
默認情況下,ribbon使用的策略是ZoneAvoidanceRule,如果服務沒有分區部署(默認情況下,我們的zone都是defaultZone),那麼其實ZoneAvoidanceRule就會退化爲AvailabilityFilteringRule。
關於如何配置不同的策略,請參見:結合ribbon