API網(wǎng)關(guān)的請求轉(zhuǎn)發(fā)等內(nèi)容實際上是通過Ribben來實現(xiàn)的。
Spring Cloud 實現(xiàn)負載均衡通過在RestTemplates? 增加@LoadBalanced注解,將Rest請求交給Ribben去管理绒北。
Spring Cloud實現(xiàn)負載主要是用過管理Rest請求來實現(xiàn),故項目中必須都使用Rest分格的請求.
Ribben的配置類LoadBalanceAutoConfiguration主要實現(xiàn)的功能:
????1.創(chuàng)建了一個LoadBalanceInterceptor的Bean速蕊,用于實現(xiàn)對客戶端發(fā)起的請求就行攔途乃,是實現(xiàn)客戶端的負載均衡。
????2.創(chuàng)建了一個LoadBalanceCustomizer的Bean? 用于給RestTemplate增加LoadBalanceInterceptor攔截器幻枉。
????3.維護了一個被@LoadBalance注釋的RestTemplate的對象列表碰声,并在這里進行初始化,通過調(diào)用LoadBalanceCustomizer的實例來給需要客戶端負載均衡的TestTemplate增加LoadBalanceInterceptor攔截器熬甫。
????4胰挑、LoadBalanceInterceptor攔截去會根據(jù)傳入的ServiceID去獲取具體的實例,攔截去實現(xiàn)的各個方法椿肩,
????addServices :向負載均衡器維護的列表中添加服務(wù)實例,添加服務(wù)的時候會將新加入的實例和之前的所有實例加入List中
????chooseServices:通過Rule(線性輪訓瞻颂、按權(quán)重負載、按流量負載)和 Ping來選擇具體的服務(wù)實例啟動的ping的定時任務(wù)默10秒
????markServiecsDowe:標示異常的服務(wù)實例
????getReachableService:獲取當前正常的服務(wù)實例
????getAllServices:獲取所有維護的服務(wù)實例
????5.Ribben 的服務(wù)實例由Eureka的服務(wù)發(fā)現(xiàn)來獲取郑象,Ribben會將Eureka中注冊章的服務(wù)轉(zhuǎn)換成自己的服務(wù)實例信息贡这。(請求了Eureka的獲取服務(wù)列表)
????6.Ribben 的服務(wù)更新器主要通過DynamicServiceListLoadBalancer 來實現(xiàn)
????7.Ribben實服務(wù)實例和真實地址之間轉(zhuǎn)換的原理,從Netfix的service中獲取host和port 如果service中的host和port中的地址和真實地中中的一直則直接返回真實地址厂榛,如果不一致則使用service中的host和port結(jié)合真實地址中的相關(guān)參數(shù)盖矫,拼接成新的地址丽惭。
*負載均衡的策略實現(xiàn)
? ??1、隨機規(guī)則(RandomRule)
在choose的時候 使用一個所有服務(wù)列表(allList)數(shù)中取隨機數(shù)去可用服務(wù)(upList)中取可用的服務(wù)炼彪,如果取到的服務(wù)不可用或者無此服務(wù)吐根,線程讓步(Thread.yield())進行線程讓我重新獲取新的服務(wù)。
? ??2辐马、線性輪訓規(guī)則(RoundRobinRule)
線性輪訓和RandomRule相似拷橘,存了循環(huán)條件以外增加了10次的輪訓限制,如果10次沒有獲取到可用的服務(wù)喜爷,則返回 No available alive serivces after 10 tries? from load balancer.....
? ??3冗疮、重試規(guī)則(RetryRule)
RetryRule增加了一個重試機制,此機制默認使用 RoundRobinRule規(guī)則來獲取服務(wù)檩帐,通知定義了一個重試時間(maxRetryMillis)术幔,如果在重試時間內(nèi)沒有獲取到可用的服務(wù),則重復(fù)進行獲取湃密,如果超出重試時間還未獲取到則返回null
? ??4诅挑、WeightedResponseTimeRule(反饋權(quán)重規(guī)則)
該策略主要是對RoundRobinRule規(guī)則的擴展,根據(jù)實例的運行情況計算權(quán)重泛源,并根據(jù)權(quán)重來選擇實例拔妥,以達到最優(yōu)的分配效果
主要實現(xiàn)有3個
1、定時任務(wù)計算權(quán)重达箍,初始化的時候啟動一個30秒的定時任務(wù)來計算服務(wù)的權(quán)重
2没龙、權(quán)重計算? ? 權(quán)重計算先獲取所有實例服務(wù)的平均響應(yīng)時間獲取平均響應(yīng)時間的總和,然后逐個計算每個實例的權(quán)重(WeigthSoFar+totalResponseTime-實例的平均響應(yīng)時間)
3缎玫、選擇實例? 判斷最小權(quán)重是否大于0.001 如果小于0.001則使用線性輪訓的策略硬纤,否則 生成一個[0,最大權(quán)重值]的隨機數(shù)赃磨,選擇一個區(qū)間內(nèi)的隨機數(shù)筝家,選擇隨機數(shù)所在區(qū)間內(nèi)的服務(wù)。
? ??5邻辉、ClientConfigEnableRoundRobinRule
內(nèi)部使用RoundRobinRule規(guī)則來實現(xiàn)策略肛鹏,但是經(jīng)常繼承這個類來實現(xiàn)高級策略的制定
? ??6、BestAvailableRule(選擇最空閑的服務(wù))
繼承了CIientConfigEnableRoundRobinRule規(guī)則恩沛,在實現(xiàn)時注入了負載均衡器的統(tǒng)計對象LoadBalacneStats ,同時在選擇實例的時候利用LoadBalaceStats來統(tǒng)計信息來來選擇滿足要求的實例
如果第一次請求LoadBalacneStats 為null,會使用線性輪訓的方式來獲取滿足要求的實例缕减,之后每選擇都會統(tǒng)計LoadBalacneStats 雷客,之后選擇的時候會選擇請求最少的服務(wù)。
????7桥狡、PredicateBasedRule
基于委托的方式來過濾清單的一種策略搅裙,在選擇服務(wù)的時候先將獲取到的服務(wù)清單通過Predicate配置的過濾條件來過濾一部分服務(wù)皱卓,然后再通過線性輪訓的方式來進行服務(wù)選擇。實現(xiàn)過濾使用的com.google.commom.base.pridicate中的apply來實現(xiàn)的部逮,new Predicate(loadBalanceKey,service),關(guān)于服務(wù)的統(tǒng)計信息和負載均衡器的選擇算法傳遞股過來的key來過濾娜汁、
............
Ribben注入的時候會進行一些自動化的配置,自動構(gòu)建一下接口來提供使用
IClientConfig? 來配置Ribben客戶端的簡單配置
IPing? 來實現(xiàn)Ribben的實例檢查策略
IRule 來實現(xiàn)負載均衡的策略? 默認采用區(qū)域感知
ServiceList ;實現(xiàn)服務(wù)清單的維護機制
ServivcerFilterList 來實現(xiàn)服務(wù)過濾規(guī)則? 默認采用區(qū)域感知
ILoadBalance 負載均衡區(qū) 默認采用區(qū)域感知
可以在創(chuàng)建Ribben的時候創(chuàng)建一個Configuration來定義以上的接口來覆蓋默認的配置兄朋。