SpringCloud Netflix Ribbon源碼解析(推薦)
SpringCloud Netflix Ribbon源碼解析
首先會(huì)介紹Ribbon 相關(guān)的配置和實(shí)例的初始化過程,然后講解Ribbon 是如何與OpenFeign 集成的,接著講解負(fù)載均衡器LoadBalancerCli ent , 最后依次講解ILoadB alancer的實(shí)現(xiàn)和負(fù)載均衡策略Rule 的實(shí)現(xiàn)。
配置和實(shí)例初始化
@RibbonClient 注解可以聲明Ribbon 客戶端,設(shè)置Ribbon 客戶端的名稱和配置類,configuration 屬性可以指定@Configuration 的配置類,進(jìn)行Ribbon 相關(guān)的配置。@RibbonClient還會(huì)導(dǎo)入( import ) RibbonClientConfigurationRegistrar 類來動(dòng)態(tài)注冊(cè)Ribbon 相關(guān)的BeanDefinition。
RibbonClientConfigurationRegistrar 是ImportBeanDefinitionRegistrar 的實(shí)現(xiàn)類,ImportBeanDefinitionRegistrar 是Spring 動(dòng)態(tài)注冊(cè)BeanDefinition 的接口, 可以用來注冊(cè)Ribbon 所需的BeanD的iition , 比如說Ribbon客戶端實(shí)例( Ribbon Client ) lmportBeanDefinitionRegistrar的registerBeanDefinitions 方法可以注冊(cè)Ribbon 客戶端的配置類, 也就是@RibbonClient 的configuration 屬性值
與OpenFeign 的集成
FeignCJientFactoryBean 是創(chuàng)造FeignClient 的工廠
類,在其getObject 方法中有一個(gè)分支判斷,當(dāng)請(qǐng)求URL 不為空時(shí), 就會(huì)生成一個(gè)具有負(fù)載均衡的FeignClient 。在這個(gè)過程中, OpenFeign 就默認(rèn)引入了Ribbon 的負(fù)載均衡實(shí)現(xiàn).
LoadBalancerFeignClient#execute 方法會(huì)將普通的Request 對(duì)象轉(zhuǎn)化為RibbonRequest , 并使用FeignLoadBalancer 實(shí)例來發(fā)送RibbonRequest。execute 方法會(huì)首先將Request 的URL轉(zhuǎn)化為對(duì)應(yīng)的服務(wù)名稱,然后構(gòu)造出RibbonRequest 對(duì)象,接著調(diào)用lbClient 方法來生成FeignLoadBalancer 實(shí)例,最后調(diào)用FeignLoadBalancer 實(shí)例的executeWithLoadBalancer 方法來處理網(wǎng)絡(luò)請(qǐng)求。
//LoadBalancerFeignClient java public Response execute(Reqest reqi且est, Request .Options options) throws 工OException { try { // :負(fù)載均衡時(shí), host 就是需要調(diào)用的服務(wù)的名稱 URI asurn= URI . create(request.url()) ; String clientName = asur. getHost(); URI ur 工WithoutHost = cleanUrl(reqi且est . url(), cl 工entName) ; //構(gòu)造RibbonRequest,delegate 一般就是真正發(fā)送網(wǎng)絡(luò)請(qǐng)求的客戶端,比如說OkHttpClient 和ApacheClient Fe 工gnLoadBalancer . R 工bbonRequest ribbonRequest = new FeignLoadBalancer . RibbonRequest( this . delegate , re 守uest , ur 工WithoutHost) ; IClientConfig requestConfig = getClientConfig(options, clientName) ; //executeWithLoadBalancer是進(jìn)行負(fù)載均衡的關(guān)鍵 return lbClient(clientName) . executeWithLoadBalancer(ribbonRequest , requestConfig) . toResponse () ; catch (ClientException e) { IOException io = findIOException(e) ; if ( io ! = null) { throw io; throw new RuntimeException(e) ; private FeignLoadBalancer lbCl 工ent(Str 工ng cl 工entName) { //調(diào)用CachingSpringLoadBalancerFactory 類的create方法。 return this . lbClientFactory . create(clientName) ;
lbClientFactory 的參數(shù)是CachingSpringLoadBalancerFactory 的實(shí)例, 它是帶有緩存機(jī)制的FeignLoadBalancer 的工廠類。
create 方法的clientName 參數(shù)是指HTTP 請(qǐng)求對(duì)應(yīng)的服務(wù)端名稱, 它會(huì)首先使用這個(gè)名稱去緩存中查找是否已經(jīng)存在對(duì)應(yīng)的實(shí)例。如果沒有, 再根據(jù)系統(tǒng)是否支持請(qǐng)求重試來創(chuàng)建出不同的F eignLoadBalancer 實(shí)例, 最后將該實(shí)例存儲(chǔ)到緩存中.
FeignLoadBalancer 是OpenFeign 在不需要重試機(jī)制的情況下默認(rèn)的負(fù)載均衡實(shí)現(xiàn)。它的execute 方法的實(shí)現(xiàn)很簡單,使用RibbonRequest 對(duì)象的客戶端來發(fā)送網(wǎng)絡(luò)請(qǐng)求,然后
將Response 包裝成RibbonResponse 進(jìn)行返回。RibbonRequest 的request 方法返回的對(duì)象就是構(gòu)造RibbonRequest 對(duì)象時(shí)傳入的delegate 參數(shù)。該參數(shù)是Client 接口的實(shí)例, Client接口是OpenFeign 真正發(fā)送網(wǎng)絡(luò)請(qǐng)求的客戶端, 比如說OkHttpClient 和ApacheClient 。FeignLoadBalancer 的execute 方法如下所示:
//Fe i gnLoadBalancer. ] ava public RibbonResponse execute(RibbonRequest request , IClientConfig configOverride) throws IOException { Request.Options options ; if (configOverride ! = null) { RibbonPropert 工es override = RibbonPropertes . from(configOverride); options = new Request.Options( else { override . connectTimeout(th 工s . connect Timeout), override . readTimeout(this . readT 工meout)); options = new Request . Options(th 工s.connectTimeout, this readTimeout); Response response = request . client() . execute(request . toReqest(), options) ; return new RibbonResponse(request . getUri() , response) ;
FeignLoadBalancer 是AbstractLoadBalancerAwareC!ient 的子類,其executeWithLoadBalance方法會(huì)首先創(chuàng)建一個(gè)LoadBalancerCommand 實(shí)例,然后在該實(shí)例的submit 方法的回調(diào)中調(diào)用子類的execute方法
其中, buildLoadB a lan cerCommand 方法使用了LoadBalancerCommand.Builder 來創(chuàng)建LoadBalancerCornmand 實(shí)例,并將AbstractLoadBalancerAwareC!ient 作LoadBalancerContext接口的實(shí)例設(shè)置給LoadBalancerCommand 實(shí)例
LoadBalancerContext 的getServerFromLoadBalancer 方法調(diào)用了ILoadBalancer 的chooseServer方法,從而完成了負(fù)載均衡中服務(wù)器的選擇。
負(fù)載均衡器LoadBalancerClient
LoadBalancerClient是Ribbon 項(xiàng)目的核心類之一,可以在RestTemplate 發(fā)送網(wǎng)絡(luò)請(qǐng)求時(shí)替代RestTemplate 進(jìn)行網(wǎng)絡(luò)調(diào)用
LoadBalancerClient 接口繼承了ServicelnstanceChooser 接口,其choose 方法可以從服務(wù)器列表中依據(jù)負(fù)載均衡策略選出一個(gè)服務(wù)器實(shí)例
RibbonLoadBalancerClient 是LoadBalancerClient 的實(shí)現(xiàn)類之一, 它的execute 方法會(huì)首先使用ILoadBa lancer 來選擇服務(wù)器實(shí)例( Server ),然后將該服務(wù)器實(shí)例封裝成RibbonServer 對(duì)象, 最后再調(diào)用LoadBalancerRequest 的apply 方法進(jìn)行網(wǎng)絡(luò)請(qǐng)求的處理。
ILoadBalancer
ILoadBalancer 是Ribbon 的關(guān)鍵類之二, 它是定義負(fù)載均衡操作過程的接口。Ribbon通過SpringClientFactory 工廠類的getLoadBalancer 方法可以獲取ILoadBalancer 實(shí)例。根據(jù)Ribbon 的組件實(shí)例化機(jī)制, ILoadBalnacer 實(shí)例是在RibbonAutoConfiguration 中被創(chuàng)建生成的。
SpringClientFactory 中的實(shí)例都是RibbonClientConfiguration 或者自定義C onfiguration配置類創(chuàng)建的Bean 實(shí)例。RibbonClientConfiguration 還創(chuàng)建了Rule 、IPing 和S e rver List
等相關(guān)組件的實(shí)例。使用者可以通過自定義配置類給出上述幾個(gè)組件的不同實(shí)例。
負(fù)載均衡策略實(shí)現(xiàn)
lRule 是定義Ribbon 負(fù)載均衡策略的接口,你可以通過實(shí)現(xiàn)該接口來自定義自己的負(fù)載均衡策略, Ribbon ClientConfiguration 配置類則會(huì)給出!Rule 的默認(rèn)實(shí)例,Rule 接口的choose 方法就是從一堆服務(wù)器中根據(jù)一定規(guī)則選出一個(gè)服務(wù)器。Rule 有很多默認(rèn)的實(shí)現(xiàn)類,這些實(shí)現(xiàn)類根據(jù)不同的算法和邏輯來進(jìn)行負(fù)載均衡。
在大多數(shù)情況下, 這些默認(rèn)的實(shí)現(xiàn)類是可以滿足需求的,如果有特殊需求,可以自己實(shí)現(xiàn)。Ribbon 內(nèi)置的Rule 子類如下所示。
- BestAvailableRule :選擇最小請(qǐng)求數(shù)的服務(wù)器。
- ClientConfigEnabledRoundRobinRule :使用RandomRobinRule 隨機(jī)選擇一個(gè)服務(wù)器。
- RoundRobinRul e :以RandonRobin 方法輪詢選擇服務(wù)器。
- RetryRule : 在選定的負(fù)載均衡策略上添加重試機(jī)制。
- WeightedResponseTimeRule :根據(jù)響應(yīng)時(shí)間去計(jì)算一個(gè)權(quán)重( we ight ) ,響應(yīng)時(shí)間越
- 長,權(quán)重越低,權(quán)重越低的服務(wù)器,被選擇的可能性就越低。
- ZoneAvoidanceRule :根據(jù)服務(wù)器所屬的服務(wù)區(qū)的整體運(yùn)行狀況來輪詢選擇。
到此這篇關(guān)于SpringCloud Netflix Ribbon源碼解析(推薦)的文章就介紹到這了,更多相關(guān)SpringCloud Netflix Ribbon源碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java經(jīng)理與員工的差異實(shí)現(xiàn)方法
這篇文章主要介紹了Java經(jīng)理與員工的差異實(shí)現(xiàn)方法,需要的朋友可以參考下2014-03-03Spring需要三個(gè)級(jí)別緩存解決循環(huán)依賴原理解析
這篇文章主要為大家介紹了Spring需要三個(gè)級(jí)別緩存解決循環(huán)依賴原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Java Web項(xiàng)目中Spring框架處理JSON格式數(shù)據(jù)的方法
Spring MVC是個(gè)靈活的框架,返回JSON數(shù)據(jù)的也有很多五花八門的方式,這里我們來整理一個(gè)最簡單的Java Web項(xiàng)目中Spring框架處理JSON格式數(shù)據(jù)的方法:2016-05-05SpringBoot @value注解動(dòng)態(tài)刷新問題小結(jié)
@Value注解 所對(duì)應(yīng)的數(shù)據(jù)源來自項(xiàng)目的 Environment 中,我們可以將數(shù)據(jù)庫或其他文件中的數(shù)據(jù),加載到項(xiàng)目的 Environment 中,然后 @Value注解 就可以動(dòng)態(tài)獲取到配置信息了,這篇文章主要介紹了SpringBoot @value注解動(dòng)態(tài)刷新,需要的朋友可以參考下2023-09-09Spring AOP中定義切點(diǎn)的實(shí)現(xiàn)方法示例
這篇文章主要介紹了Spring AOP中定義切點(diǎn)的實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了spring面向切面AOP定義切點(diǎn)的具體步驟、實(shí)現(xiàn)方法與相關(guān)操作技巧,需要的朋友可以參考下2020-01-01Java多線程案例實(shí)戰(zhàn)之定時(shí)器的實(shí)現(xiàn)
在Java中可以使用多線程和定時(shí)器來實(shí)現(xiàn)定時(shí)任務(wù),下面這篇文章主要給大家介紹了關(guān)于Java多線程案例之定時(shí)器實(shí)現(xiàn)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01Java基礎(chǔ)強(qiáng)化訓(xùn)練輸入錯(cuò)誤即結(jié)束進(jìn)程
本文主要介紹了Java編程的基礎(chǔ)知識(shí)強(qiáng)化應(yīng)用,文中實(shí)例涉及到了許多基礎(chǔ)知識(shí),new對(duì)象,控制臺(tái)輸入,if語句等。很實(shí)用,需要的朋友可以參考下2017-09-09