0
点赞
收藏
分享

微信扫一扫

Ribbon源码分析


文章目录

  • ​​1.LoadBalancerInterceptor​​
  • ​​2.RibbonLoadBalancerClient​​
  • ​​3.ZoneAwareLoadBalancer​​
  • ​​4.BaseLoadBalancer​​
  • ​​5.默认的RoundRobinRule何时被覆盖?​​
  • ​​5.1.RibbonClientConfiguration​​
  • ​​5.2.何时替换了RoundRobinRule​​
  • ​​6.PredicateBasedRule的choose​​
  • ​​7.AbstractServerPredicate的chooseRoundRobinAfterFiltering​​
  • ​​8.进行过滤器过滤​​
  • ​​9.Predicates​​
  • ​​10.ZoneAvoidancePredicate区域过滤器​​
  • ​​11.AvailabilityPredicate可用性过滤器​​
  • ​​12.执行过滤之后​​
  • ​​13.常见的负载均衡算法​​

1.LoadBalancerInterceptor

为什么我们只输入了​​service​​​名称就可以访问了呢?之前还要获取ip和端口。显然有人帮我们根据service名称,获取到了服务实例的ip和端口。它就是​​LoadBalancerInterceptor​​​Ribbon源码分析_spring cloud

org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient

2.RibbonLoadBalancerClient

Ribbon源码分析_服务器_02
Ribbon源码分析_负载均衡_03

3.ZoneAwareLoadBalancer

Ribbon源码分析_eureka_04
调用父类的​​​chooseServer​

4.BaseLoadBalancer

Ribbon源码分析_spring cloud_05
内部规则是​​​ZoneAvoidanceRule​​​,就是前面说的把默认的​​RoundRobinRule​​​给覆盖了,但是复合策略里面默认的又是​​RoundRobinRule​​​,只是加了一些过滤器,根据一些条件过滤服务器。
Ribbon源码分析_服务器_06

5.默认的RoundRobinRule何时被覆盖?

5.1.RibbonClientConfiguration

Ribbon源码分析_服务器_07

5.2.何时替换了RoundRobinRule

Ribbon源码分析_服务器_08

6.PredicateBasedRule的choose

Ribbon源码分析_服务器_09

最终到父类的choose方法,先获取负载均衡器lb,然后获取所有的服务器,再获取预测器​​getPredicate​​​,里面是个复合的​​AbstractServerPredicate​​​,可以当做过滤器,满足一定条件过滤服务器的,最后进行​​chooseRoundRobinAfterFiltering​​轮询:

7.AbstractServerPredicate的chooseRoundRobinAfterFiltering

必须先走过滤器,过滤一遍,然后再轮询出服务器。
Ribbon源码分析_服务器_10

8.进行过滤器过滤

Ribbon源码分析_负载均衡_11
内部最终会进行​​​ZoneAvoidancePredicate​​​和​​AvailabilityPredicate​​两个过滤器的过滤,只要有一个不满足就被过滤掉了。

9.Predicates

Ribbon源码分析_spring cloud_12

10.ZoneAvoidancePredicate区域过滤器

我们一般默认就一个区域defaultzone,多个区域就需要有判断了,比如断电情况,负载这些,具体可以看​​ZoneAvoidancePredicate​​​的apply方法。一般情况只有一个区域,就返回true了:
Ribbon源码分析_eureka_13

11.AvailabilityPredicate可用性过滤器

这个是用来过滤掉不可用的服务器,不如连接不上,还有并发太多的
Ribbon源码分析_服务器_14
如果检测出断路器问题或者是服务器连接数超过限制了,就要过滤掉了。
Ribbon源码分析_负载均衡_15

12.执行过滤之后

最后过滤出来的服务器集合再进行轮询算法,选出一个。
Ribbon源码分析_负载均衡_16
核心的​​​incrementAndGetModulo(int)​​方法

老版本源码

private int incrementAndGetModulo(int modulo) {
int current;
int next;
do {
current = this.nextServerCyclicCounter.get(); //nextServerCyclicCounter是AtomicInteger对象,默认值0,可保证线程安全性
next = (current + 1) % modulo; //每次往后移一位,取集合中的下一个server。这里要注意的是从1开始,即数组中的第二个server会被第一个调用。
} while(!this.nextServerCyclicCounter.compareAndSet(current, next)); //操作完成后用CAS操作将next赋值给nextServerCyclicCounter

return next;
}

新版本源码Ribbon源码分析_ribbon_17

13.常见的负载均衡算法

IRule是以下七种负载均衡算法的父接口
Ribbon源码分析_负载均衡_18
说明:
Ribbon源码分析_ribbon_19


举报

相关推荐

0 条评论