SpringCloud Netflix Ribbon源码解析(推荐)

 更新时间:2021年03月22日 14:43:12   作者:码上代码  
这篇文章主要介绍了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源码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何将默认的maven仓库改为阿里的maven仓库

    如何将默认的maven仓库改为阿里的maven仓库

    这篇文章主要介绍了如何将默认的maven仓库改为阿里的maven仓库,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • SpringBoot Redis清除所有的key的实现方法

    SpringBoot Redis清除所有的key的实现方法

    本文主要介绍了SpringBoot Redis清除所有的key的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Spring boot集成RabbitMQ的示例代码

    Spring boot集成RabbitMQ的示例代码

    本篇文章主要介绍了Spring boot集成RabbitMQ的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Spring-webflux访问关系型数据库实战

    Spring-webflux访问关系型数据库实战

    这篇文章主要为大家介绍了Spring-webflux访问关系型数据库实战详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Java注解如何基于Redission实现分布式锁

    Java注解如何基于Redission实现分布式锁

    这篇文章主要介绍了Java注解如何基于Redission实现分布式锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Java Session会话追踪原理深入分析

    Java Session会话追踪原理深入分析

    web开发阶段我们主要是浏览器和服务器之间来进行交互。浏览器和服务器之间的交互就像人和人之间进行交流一样,但是对于机器来说,在一次请求之间只是会携带着本次请求的数据的,但是可能多次请求之间是会有联系的,所以提供了会话机制
    2022-11-11
  • 详细介绍idea如何设置类头注释和方法注释(图文)

    详细介绍idea如何设置类头注释和方法注释(图文)

    本篇文章主要介绍了idea如何设置类头注释和方法注释(图文),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • 如何使用@ConditionalOnExpression决定是否生效注释

    如何使用@ConditionalOnExpression决定是否生效注释

    这篇文章主要介绍了如何使用@ConditionalOnExpression决定是否生效注释的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 详解Spring Boot实现日志记录 SLF4J

    详解Spring Boot实现日志记录 SLF4J

    本篇文章主要介绍了详解Spring Boot实现日志记录 SLF4J,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • 使用SpringBoot跨系统调用接口的方案

    使用SpringBoot跨系统调用接口的方案

    这篇文章主要介绍了使用SpringBoot跨系统调用接口的方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01

最新评论