SpringCloud Netflix Ribbon源碼解析(推薦)

SpringCloud Netflix Ribbon源碼解析

首先會介紹Ribbon 相關的配置和實例的初始化過程,然後講解Ribbon 是如何與OpenFeign 集成的,接著講解負載均衡器LoadBalancerCli ent , 最後依次講解ILoadB alancer的實現和負載均衡策略Rule 的實現。

在這裡插入圖片描述

配置和實例初始化

@RibbonClient 註解可以聲明Ribbon 客戶端,設置Ribbon 客戶端的名稱和配置類,configuration 屬性可以指定@Configuration 的配置類,進行Ribbon 相關的配置。@RibbonClient還會導入( import ) RibbonClientConfigurationRegistrar 類來動態註冊Ribbon 相關的BeanDefinition。
RibbonClientConfigurationRegistrar 是ImportBeanDefinitionRegistrar 的實現類,ImportBeanDefinitionRegistrar 是Spring 動態註冊BeanDefinition 的接口, 可以用來註冊Ribbon 所需的BeanD的iition , 比如說Ribbon客戶端實例( Ribbon Client ) lmportBeanDefinitionRegistrar的registerBeanDefinitions 方法可以註冊Ribbon 客戶端的配置類, 也就是@RibbonClient 的configuration 屬性值

與OpenFeign 的集成

FeignCJientFactoryBean 是創造FeignClient 的工廠
類,在其getObject 方法中有一個分支判斷,當請求URL 不為空時, 就會生成一個具有負載均衡的FeignClient 。在這個過程中, OpenFeign 就默認引入瞭Ribbon 的負載均衡實現.

在這裡插入圖片描述

LoadBalancerFeignClient#execute 方法會將普通的Request 對象轉化為RibbonRequest , 並使用FeignLoadBalancer 實例來發送RibbonRequest。execute 方法會首先將Request 的URL轉化為對應的服務名稱,然後構造出RibbonRequest 對象,接著調用lbClient 方法來生成FeignLoadBalancer 實例,最後調用FeignLoadBalancer 實例的executeWithLoadBalancer 方法來處理網絡請求。

//LoadBalancerFeignClient java
public Response execute(Reqest reqi且est, Request .Options options) throws 工OException {
try {
// :負載均衡時, host 就是需要調用的服務的名稱
URI asurn= URI . create(request.url()) ;
String clientName = asur. getHost();
URI ur 工WithoutHost = cleanUrl(reqi且est . url(), cl 工entName) ;
//構造RibbonRequest,delegate 一般就是真正發送網絡請求的客戶端,比如說OkHttpClient
和ApacheClient
Fe 工gnLoadBalancer . R 工bbonRequest ribbonRequest = new FeignLoadBalancer .
RibbonRequest(
this . delegate , re 守uest , ur 工WithoutHost) ;
IClientConfig requestConfig = getClientConfig(options, clientName) ;
//executeWithLoadBalancer是進行負載均衡的關鍵
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) {
//調用CachingSpringLoadBalancerFactory 類的create方法。
return this . lbClientFactory . create(clientName) ;

lbClientFactory 的參數是CachingSpringLoadBalancerFactory 的實例, 它是帶有緩存機制的FeignLoadBalancer 的工廠類。

create 方法的clientName 參數是指HTTP 請求對應的服務端名稱, 它會首先使用這個名稱去緩存中查找是否已經存在對應的實例。如果沒有, 再根據系統是否支持請求重試來創建出不同的F eignLoadBalancer 實例, 最後將該實例存儲到緩存中.

在這裡插入圖片描述

FeignLoadBalancer 是OpenFeign 在不需要重試機制的情況下默認的負載均衡實現。它的execute 方法的實現很簡單,使用RibbonRequest 對象的客戶端來發送網絡請求,然後
將Response 包裝成RibbonResponse 進行返回。RibbonRequest 的request 方法返回的對象就是構造RibbonRequest 對象時傳入的delegate 參數。該參數是Client 接口的實例, Client接口是OpenFeign 真正發送網絡請求的客戶端, 比如說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方法會首先創建一個LoadBalancerCommand 實例,然後在該實例的submit 方法的回調中調用子類的execute方法

在這裡插入圖片描述

其中, buildLoadB a lan cerCommand 方法使用瞭LoadBalancerCommand.Builder 來創建LoadBalancerCornmand 實例,並將AbstractLoadBalancerAwareC!ient 作LoadBalancerContext接口的實例設置給LoadBalancerCommand 實例

LoadBalancerContext 的getServerFromLoadBalancer 方法調用瞭ILoadBalancer 的chooseServer方法,從而完成瞭負載均衡中服務器的選擇。

負載均衡器LoadBalancerClient

LoadBalancerClient是Ribbon 項目的核心類之一,可以在RestTemplate 發送網絡請求時替代RestTemplate 進行網絡調用

LoadBalancerClient 接口繼承瞭ServicelnstanceChooser 接口,其choose 方法可以從服務器列表中依據負載均衡策略選出一個服務器實例

RibbonLoadBalancerClient 是LoadBalancerClient 的實現類之一, 它的execute 方法會首先使用ILoadBa lancer 來選擇服務器實例( Server ),然後將該服務器實例封裝成RibbonServer 對象, 最後再調用LoadBalancerRequest 的apply 方法進行網絡請求的處理。

ILoadBalancer

ILoadBalancer 是Ribbon 的關鍵類之二, 它是定義負載均衡操作過程的接口。Ribbon通過SpringClientFactory 工廠類的getLoadBalancer 方法可以獲取ILoadBalancer 實例。根據Ribbon 的組件實例化機制, ILoadBalnacer 實例是在RibbonAutoConfiguration 中被創建生成的。

SpringClientFactory 中的實例都是RibbonClientConfiguration 或者自定義C onfiguration配置類創建的Bean 實例。RibbonClientConfiguration 還創建瞭Rule 、IPing 和S e rver List
等相關組件的實例。使用者可以通過自定義配置類給出上述幾個組件的不同實例。

負載均衡策略實現

lRule 是定義Ribbon 負載均衡策略的接口,你可以通過實現該接口來自定義自己的負載均衡策略, Ribbon ClientConfiguration 配置類則會給出!Rule 的默認實例,Rule 接口的choose 方法就是從一堆服務器中根據一定規則選出一個服務器。Rule 有很多默認的實現類,這些實現類根據不同的算法和邏輯來進行負載均衡。

在這裡插入圖片描述

在大多數情況下, 這些默認的實現類是可以滿足需求的,如果有特殊需求,可以自己實現。Ribbon 內置的Rule 子類如下所示。

  • BestAvailableRule :選擇最小請求數的服務器。
  • ClientConfigEnabledRoundRobinRule :使用RandomRobinRule 隨機選擇一個服務器。
  • RoundRobinRul e :以RandonRobin 方法輪詢選擇服務器。
  • RetryRule : 在選定的負載均衡策略上添加重試機制。
  • WeightedResponseTimeRule :根據響應時間去計算一個權重( we ight ) ,響應時間越
  • 長,權重越低,權重越低的服務器,被選擇的可能性就越低。
  • ZoneAvoidanceRule :根據服務器所屬的服務區的整體運行狀況來輪詢選擇。

到此這篇關於SpringCloud Netflix Ribbon源碼解析(推薦)的文章就介紹到這瞭,更多相關SpringCloud Netflix Ribbon源碼內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: