Ribbon源码解析
Ribbon源码解析1. LoadBalancerClient2. BaseLoadBalancer3. DynamicServerListLoadBalancer4. IRule5. IPing6. DynamicServerListLoadBalancer与Eureka7. Ribbon更新数据的时间8. @LoadBalancergit地址https://github.com/a1879..._ribbonloadbalancerclient.choose 重写
文章信息
- 原文链接: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去处理,从而达到了负载均衡的目的。






