在上篇博客(Spring Cloud中負載均衡器概覽)中,咱們大體的瞭解了一下Spring Cloud中有哪些負載均衡器,可是對於負載均衡策略咱們並無去詳細瞭解,咱們只是知道在BaseLoadBalancer的chooseServer方法中,調用了IRule中的choose方法來找到一個具體的服務實例,IRule是一個接口,在BaseLoadBalancer它的默認實現是RoundRobinRule類,RoundRobinRule類中採用了最經常使用的線性負載均衡規則,也就是全部有效的服務端輪流調用,對於其餘的負載均衡策略則沒有深刻去了解,那麼本文咱們就來看看Spring Cloud中都有哪些負載均衡策略。併發
本文是Spring Cloud系列的第九篇文章,瞭解前八篇文章內容有助於更好的理解本文: 負載均衡
1.使用Spring Cloud搭建服務註冊中心
2.使用Spring Cloud搭建高可用服務註冊中心
3.Spring Cloud中服務的發現與消費
4.Eureka中的核心概念
5.什麼是客戶端負載均衡
6.Spring RestTemplate中幾種常見的請求方式
7.RestTemplate的逆襲之路,從發送請求到負載均衡
8.Spring Cloud中負載均衡器概覽dom
上篇文章中,咱們看到服務實例的選擇最終調用了IRule的choose方法,而IRule是一個接口,咱們先來看一張這個接口的實現類結構圖: 函數
OK,接下來咱們就一個一個來看。spa
這是全部負載均衡策略的父接口,裏邊的核心方法就是choose方法,用來選擇一個服務實例。3d
AbstractLoadBalancerRule是一個抽象類,裏邊主要定義了一個ILoadBalancer,就是咱們上文所說的負載均衡器,負載均衡器的功能咱們在上文已經說的很詳細了,這裏就再也不贅述,這裏定義它的目的主要是輔助負責均衡策略選取合適的服務端實例。code
看名字就知道,這種負載均衡策略就是隨機選擇一個服務實例,看源碼咱們知道,在RandomRule的無參構造方法中初始化了一個Random對象,而後在它重寫的choose方法又調用了choose(ILoadBalancer lb, Object key)
這個重載的choose方法,在這個重載的choose方法中,每次利用random對象生成一個不大於服務實例總數的隨機數,並將該數做爲下標因此獲取一個服務實例。server
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中又定義了一個subRule,它的實現類是RoundRobinRule,而後在RetryRule的choose(ILoadBalancer lb, Object key)
方法中,每次仍是採用RoundRobinRule中的choose規則來選擇一個服務實例,若是選到的實例正常就返回,若是選擇的服務實例爲null或者已經失效,則在失效時間deadline以前不斷的進行重試(重試時獲取服務的策略仍是RoundRobinRule中定義的策略),若是超過了deadline仍是沒取到則會返回一個null。blog
WeightedResponseTimeRule是RoundRobinRule的一個子類,在WeightedResponseTimeRule中對RoundRobinRule的功能進行了擴展,WeightedResponseTimeRule中會根據每個實例的運行狀況來給計算出該實例的一個權重,而後在挑選實例的時候則根據權重進行挑選,這樣可以實現更優的實例調用。WeightedResponseTimeRule中有一個名叫DynamicServerWeightTask的定時任務,默認狀況下每隔30秒會計算一次各個服務實例的權重,權重的計算規則也很簡單,若是一個服務的平均響應時間越短則權重越大,那麼該服務實例被選中執行任務的機率也就越大。
ClientConfigEnabledRoundRobinRule選擇策略的實現很簡單,內部定義了RoundRobinRule,choose方法仍是採用了RoundRobinRule的choose方法,因此它的選擇策略和RoundRobinRule的選擇策略一致,不贅述。
BestAvailableRule繼承自ClientConfigEnabledRoundRobinRule,它在ClientConfigEnabledRoundRobinRule的基礎上主要增長了根據loadBalancerStats中保存的服務實例的狀態信息來過濾掉失效的服務實例的功能,而後順便找出併發請求最小的服務實例來使用。然而loadBalancerStats有可能爲null,若是loadBalancerStats爲null,則BestAvailableRule將採用它的父類即ClientConfigEnabledRoundRobinRule的服務選取策略(線性輪詢)。
PredicateBasedRule是ClientConfigEnabledRoundRobinRule的一個子類,它先經過內部定義的一個過濾器過濾出一部分服務實例清單,而後再採用線性輪詢的方式從過濾出來的結果中選取一個服務實例。
ZoneAvoidanceRule是PredicateBasedRule的一個實現類,只不過這裏多一個過濾條件,ZoneAvoidanceRule中的過濾條件是以ZoneAvoidancePredicate爲主過濾條件和以AvailabilityPredicate爲次過濾條件組成的一個叫作CompositePredicate的組合過濾條件,過濾成功以後,繼續採用線性輪詢的方式從過濾結果中選擇一個出來。
OK,以上就是Spring Cloud中一些常見的負載均衡策略,有問題歡迎留言討論。
更多JavaEE資料請關注公衆號:
以上。。