1. 程式人生 > >Spring Cloud中的負載均衡策略

Spring Cloud中的負載均衡策略

在上篇部落格(Spring Cloud中負載均衡器概覽)中,我們大致的瞭解了一下Spring Cloud中有哪些負載均衡器,但是對於負載均衡策略我們並沒有去詳細瞭解,我們只是知道在BaseLoadBalancer的chooseServer方法中,呼叫了IRule中的choose方法來找到一個具體的服務例項,IRule是一個介面,在BaseLoadBalancer它的預設實現是RoundRobinRule類,RoundRobinRule類中採用了最常用的線性負載均衡規則,也就是所有有效的服務端輪流呼叫,對於其他的負載均衡策略則沒有深入去了解,那麼本文我們就來看看Spring Cloud中都有哪些負載均衡策略。

本文是Spring Cloud系列的第九篇文章,瞭解前八篇文章內容有助於更好的理解本文:

上篇文章中,我們看到服務例項的選擇最終呼叫了IRule的choose方法,而IRule是一個介面,我們先來看一張這個介面的實現類結構圖:

這裡寫圖片描述

OK,接下來我們就一個一個來看。

IRule

這是所有負載均衡策略的父介面,裡邊的核心方法就是choose方法,用來選擇一個服務例項。

AbstractLoadBalancerRule

AbstractLoadBalancerRule是一個抽象類,裡邊主要定義了一個ILoadBalancer,就是我們上文所說的負載均衡器,負載均衡器的功能我們在上文已經說的很詳細了,這裡就不再贅述,這裡定義它的目的主要是輔助負責均衡策略選取合適的服務端例項。

RandomRule

看名字就知道,這種負載均衡策略就是隨機選擇一個服務例項,看原始碼我們知道,在RandomRule的無參構造方法中初始化了一個Random物件,然後在它重寫的choose方法又呼叫了choose(ILoadBalancer lb, Object key)這個過載的choose方法,在這個過載的choose方法中,每次利用random物件生成一個不大於服務例項總數的隨機數,並將該數作為下標所以獲取一個服務例項。

RoundRobinRule

RoundRobinRule這種負載均衡策略叫做線性負載均衡策略,也就是我們在上文所說的BaseLoadBalancer負載均衡器中預設採用的負載均衡策略。這個類的choose(ILoadBalancer lb, Object key)

函式整體邏輯是這樣的:開啟一個計數器count,在while迴圈中遍歷服務清單,獲取清單之前先通過incrementAndGetModulo方法獲取一個下標,這個下標是一個不斷自增長的數先加1然後和服務清單總數取模之後獲取到的(所以這個下標從來不會越界),拿著下標再去服務清單列表中取服務,每次迴圈計數器都會加1,如果連續10次都沒有取到服務,則會報一個警告No available alive servers after 10 tries from load balancer: XXXX

RetryRule

看名字就知道這種負載均衡策略帶有重試功能。首先RetryRule中又定義了一個subRule,它的實現類是RoundRobinRule,然後在RetryRule的choose(ILoadBalancer lb, Object key)方法中,每次還是採用RoundRobinRule中的choose規則來選擇一個服務例項,如果選到的例項正常就返回,如果選擇的服務例項為null或者已經失效,則在失效時間deadline之前不斷的進行重試(重試時獲取服務的策略還是RoundRobinRule中定義的策略),如果超過了deadline還是沒取到則會返回一個null。

WeightedResponseTimeRule

WeightedResponseTimeRule是RoundRobinRule的一個子類,在WeightedResponseTimeRule中對RoundRobinRule的功能進行了擴充套件,WeightedResponseTimeRule中會根據每一個例項的執行情況來給計算出該例項的一個權重,然後在挑選例項的時候則根據權重進行挑選,這樣能夠實現更優的例項呼叫。WeightedResponseTimeRule中有一個名叫DynamicServerWeightTask的定時任務,預設情況下每隔30秒會計算一次各個服務例項的權重,權重的計算規則也很簡單,如果一個服務的平均響應時間越短則權重越大,那麼該服務例項被選中執行任務的概率也就越大。

ClientConfigEnabledRoundRobinRule

ClientConfigEnabledRoundRobinRule選擇策略的實現很簡單,內部定義了RoundRobinRule,choose方法還是採用了RoundRobinRule的choose方法,所以它的選擇策略和RoundRobinRule的選擇策略一致,不贅述。

BestAvailableRule

BestAvailableRule繼承自ClientConfigEnabledRoundRobinRule,它在ClientConfigEnabledRoundRobinRule的基礎上主要增加了根據loadBalancerStats中儲存的服務例項的狀態資訊來過濾掉失效的服務例項的功能,然後順便找出併發請求最小的服務例項來使用。然而loadBalancerStats有可能為null,如果loadBalancerStats為null,則BestAvailableRule將採用它的父類即ClientConfigEnabledRoundRobinRule的服務選取策略(線性輪詢)。

PredicateBasedRule

PredicateBasedRule是ClientConfigEnabledRoundRobinRule的一個子類,它先通過內部定義的一個過濾器過濾出一部分服務例項清單,然後再採用線性輪詢的方式從過濾出來的結果中選取一個服務例項。

ZoneAvoidanceRule

ZoneAvoidanceRule是PredicateBasedRule的一個實現類,只不過這裡多一個過濾條件,ZoneAvoidanceRule中的過濾條件是以ZoneAvoidancePredicate為主過濾條件和以AvailabilityPredicate為次過濾條件組成的一個叫做CompositePredicate的組合過濾條件,過濾成功之後,繼續採用線性輪詢的方式從過濾結果中選擇一個出來。

OK,以上就是Spring Cloud中一些常見的負載均衡策略,有問題歡迎留言討論。

更多JavaEE資料請關注公眾號:

這裡寫圖片描述

以上。。