文章

Ribbon源码解析

Ribbon源码解析1. LoadBalancerClient2. BaseLoadBalancer3. DynamicServerListLoadBalancer4. IRule5. IPing6. DynamicServerListLoadBalancer与Eureka7. Ribbon更新数据的时间8. @LoadBalancergit地址https://github.com/a1879..._ribbonloadbalancerclient.choose 重写

Ribbon源码解析

文章信息

  • 原文链接:https://jiayq.blog.csdn.net/article/details/104503637
  • 发布时间:2020-02-25 20:49:55
  • 阅读量:487
  • 分类:微服务同时被 2 个专栏收录, 订阅专栏, spring boot
  • 标签:#Ribbon和Eureka, #BaseLoadBlc, #IRule, #IPing, #DynamicSLLB

摘要

文章浏览阅读487次。Ribbon源码解析1. LoadBalancerClient2. BaseLoadBalancer3. DynamicServerListLoadBalancer4. IRule5. IPing6. DynamicServerListLoadBalancer与Eureka7. Ribbon更新数据的时间8. @LoadBalancergit地址https://github.com/a1879…_ribbonloadbalancerclient.choose 重写


Ribbon源码解析

  • 1. LoadBalancerClient
  • 2. BaseLoadBalancer
  • 3. DynamicServerListLoadBalancer
  • 4. IRule
  • 5. IPing
  • 6. DynamicServerListLoadBalancer与Eureka
  • 7. Ribbon更新数据的时间
  • 8. @LoadBalancer

git地址
https://github.com/a18792721831/studySpringCloud.git
本文全为源码跟踪等,无实际项目。
此文主要笔记使用,基本都是从书本摘抄。

1. LoadBalancerClient

在这里插入图片描述
LoadBalancerClient是接口,有三个方法,有多个实现
在这里插入图片描述
我们主要看的就是RibbonLoadBalancerClient
其关系图如下
在这里插入图片描述
ServiceInstanceChooser接口只有一个方法。
在这里插入图片描述
那么RibbonLoadBalancerClient就实现了choose方法等
看下choose方法
在这里插入图片描述
这里调用方法getServer方法
在这里插入图片描述
这里看到最终有ILoadBalancer的chooseServer去获取的。
ILoadBalancer是一个接口,有5个方法(不包含计划删除的)
在这里插入图片描述

  • addServers添加服务集合
  • chooseServer根据key选择服务
  • markServerDown标记某个服务下线
  • getReachableServers获取可用的服务集合
  • getAllServers获取所有的集合
    ILoadBanlancer有多个实现类
    在这里插入图片描述
    在这里插入图片描述
    AbstractLoadBalancer有四个实现类
    在这里插入图片描述

2. BaseLoadBalancer

在这里插入图片描述
根据接口,其必然实现了ILoadBalancer的方法。
addServers
在这里插入图片描述
被放到了allServerList变量中
在这里插入图片描述
存在两个volatile修饰的列表,保证并发安全。还有对应的两个读写锁。。
在这里插入图片描述
使用锁进行更新。

3. DynamicServerListLoadBalancer

其关系如下
在这里插入图片描述
继承BaseLoadBalancer,聚合Server
DynamicServerListLoadBalancer需要配置IClientConfig、IRule、IPing、ServerList、ServerListFilter和ILoadBalancer.
在BaseLoadBalancer中默认实现如下配置

  • IClientConfig ribbonClientConfig:DefaultClientConfigImpl
  • IRule ribbonRule:RoundRobinRule
  • IPing ribbonPing:DummyPing
  • ServerList ribbonServerList:ConfigurationBasedServerList。
  • ServerListFilter ribbonServerListFilter:ZonePreferenceServerListFilter。
  • ILoadBalancer ribbonLoadBalancer:ZoneAwareLoadBalancer。
  • IClientConfig 用于配置负载均衡的客户端,IClientConfig 的默认实现类为 DefaultClient-
    ConfigImpl。

4. IRule

IRule 用于配置负载均衡的策略,IRule有3个方法,其中choose()是根据key来获取 server实例的,setLoadBalancer和getLoadBalancer是用来设置和获取ILoadBalancer的
在这里插入图片描述

其实现较多。
在这里插入图片描述

  • BestAvailableRule:选择最小请求数。
  • ClientConfigEnabledRoundRobinRule:轮询。
  • RandomRule:随机选择一个 server。
  • RoundRobinRule:轮询选择server。
  • RetryRule:根据轮询的方式重试。
  • WeightedResponseTimeRule:根据响应时间去分配一个 weight,weight越低,被选择的可能性就越低。
  • ZoneAvoidanceRule:根据 server 的zone区域和可用性来轮询选择。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5. IPing

在这里插入图片描述
在这里插入图片描述

  • PingUrl:真实地去ping 某个Url,判断其是否可用。
  • PingConstant:固定返回某服务是否可用,默认返回true,即可用。
  • NoOpPing:不去 ping,直接返回true,即可用。
  • DummyPing:直接返回true,并实现了 initWithNiwsConfig方法。
  • NIWSDiscoveryPing:根据 DiscoveryEnabledServer 的 InstanceInfo 的 InstanceStatus去判断,如果为InstanceStatus.UP,则可用,否则不可用。

6. DynamicServerListLoadBalancer与Eureka

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
EurekaClient的实现类为 DiscoveryClient,在上一章已经分析了。DiscoveryClient 具有服
务注册、获取服务注册列表等功能。
由此可见,负载均衡器是从 Eureka Client 获取服务列表信息的,并根据IRule的策略去路
由,根据IPing 去判断服务的可用性。

7. Ribbon更新数据的时间

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
10秒中检测一次
在这里插入图片描述
在这里插入图片描述
由此可见,LoadBalancerClient是在初始化时向Eureka获取服务注册列表信息,并且每10秒向 EurekaClient发送“ping”,来判断服务的可用性。如果服务的可用性发生了改变或者服数量和之前的不一致,则更新或者重新拉取。LoadBalancerClient有了这些服务注册列表信息就可以根据具体的IRule的策略来进行负载均衡。

8. @LoadBalancer

在这里插入图片描述
在这里插入图片描述
在 LoadBalancerAutoConfiguration 类中,首先维护了一个被@LoadBalanced修饰的RestTemplate对象的 List。在初始化的过程中,通过调用 customizer.customize(restTemplate)方法来给 RestTemplate 增加拦截器 LoadBalancerInterceptor。LoadBalancerInterceptor 用于实时拦截,在LoadBalancerInterceptor 中实现了负载均衡的方法。LoadBalancerInterceptor 类的拦截方法的代码如下:
在这里插入图片描述
综上所述,Ribbon 的负载均衡主要是通过LoadBalancerClient来实现的,而LoadBalancer-Client 具体交给了 ILoadBalancer来处理,ILoadBalancer通过配置IRule、IPing等,向 EurekaClient获取注册列表的信息,默认每10秒向EurckaClient发送一次“ping”,进而检查是否需要更新服务的注册列表信息。最后,在得到服务注册列表信息后,ILoadBalancer根据 IRule 的策略进行负载均衡。
而 RestTemplate 加上@LoadBalance 注解后,在远程调度时能够负载均衡,主要是维护了一个被@LoadBalance 注解的 RestTemplate列表,并给该列表中的RestTemplate对象添加了拦截器。在拦截器的方法中,将远程调度方法交给了 Ribbon 的负载均衡器 LoadBalancerClient去处理,从而达到了负载均衡的目的。

本文由作者按照 CC BY 4.0 进行授权