spring cloud ribbon 客户端负载均衡策略

负载均衡策略

AbstractLoadBalancerRule

负载均衡策略的抽象类,在该类中定义了负载均衡器ILoadBalancer对象,该对象能够在具体实现选择服务策略时,获取到

一些负载均衡中维护的信息来作为分配依据,并以此设计一些算法来实现针对特定场景的高效策略

RandomRule

随机选择一个服务实例

RoundRobinRule

线性轮询的方式

RetryRule

实现了一个具备重试机制的实例选择功能

WeightedResponseTimeRule

该策略是对RoundRobinRule的扩展,增加了根据实例的运行情况来计算权重,并根据权重来挑选实例,以达到更优的分配效果

   定时任务

serverWeightTimer.schedule(new DynamicServerWeightTask(), 0, serverWeightTaskTimerInterval);启动一个定时任务,

用来为每个服务实例计算权重

该方法的实现主要分为两个步骤:

  根据LoadBalancerStats中记录的每个实例的统计信息,累加所有实例的平均响应时间,得到平均响应时间总和

totalResponseTime,该值会用于后续的计算。

       为负载均衡器中维护的实例清单逐个计算权重(从第一个开始),计算规则为weightSoFar+totalResponseTime

- 实例的平均响应时间,其中weightSoFar初始为零,并且每计算好一个权重需要累加到weightSoFar上供下一次计算使用

   实例选择

   WeightedResponseTimeRule选择实例的实现与之前介绍的算法类似,下面是它主体的算法

主要分两步:

  生成一个[0, 最大权重值]区间内的随机数。

       遍历权重列表,比较权重值与随机数的大小,如果权重值大于等于随机数,就拿当前权重列表的索引值

去服务实例列表中获取具体的实例。而权重区间边界的开闭原则根据算法,正常每个区间为(x, y]的形式,

但是第一个实例和最后一个实例为什么不同,由于随机数的最小取值可以为0,所以第一个实例的下限是

闭合区,同时随机数的最大值取不到最大权重值,所以最后一个实例的上限是开区间

      若继续以上面的数据为例进行服务实例的选择,则该方法会从[0, 690)区间中选出一个随机数,比如选出的

随机数为230,由于位于第二个区间,所以此时就会选择实例B来进行请求

 

  ClientConfigEnableRoundRobinRule

  该策略较为特殊,一般不直接使用它,因为本身没有特殊的处理逻辑,内部定义了一个RoundRobinRule,

choose()方法默认使用RoundRobinRule的线性轮循机制,

 通过继承该策略,在子类中做一些高级策略时通常有可能会存在一些无法实施的情况,那么就可以用父类的实现

作为备选。

  BestAvailableRule

    ClientConfigEnableRoundRobinRule的子类,主要是找出并发请求数最小的一个

  PredicateBasedRule

      这是一个抽象策略,它也继承了ClientConfigEnabledRoundRobinRule,从其命名中可以看出这是一个

基于Predicate实现的策略,Predicate是Google Guava Collection工具对集合进行过滤的条件接口

  如下所示,它定义了一个抽象方法getPredicate()来获取AbstractServerPredicate对象的实现,而在choose()

方法中,通过AbstractServerPredicate的chooseRoundRobinAfterFiltering()方法来选出具体的服务实例

在 AbstractServerPredicate中

先通过内部定义的getEligibleServers()方法来获取备选的实例清单(过滤),如果为空,用Optional.abstent()表示

不存在,否则线性轮循

如下 是getEligibleServers()方法

使用this.apply()方法来判断是否需要保留,在子类中查apply()方法的实现

  AvailabilityFilteringRule

  该策略继承上面的抽象策略PredicateBaseRule,所以它也继承了“先过滤,再轮循”的基本逻辑,

其中过滤条件使用类AvailabilityPredicate

  AvailabilityFilterRule的choose()方法也不同

  可以看到,它并没有像父类那样,先遍历所有的节点进行过滤,然后在过滤后的集合中选择实例。而是

先以线性的方式选择一个实例,接着用过滤条件来判断该实例是否满足要求,不满足再选择下一个实例,

优化类父类每次都要遍历所有实例的开销

 

  ZoneAvoidanceRule

  它使用了CompositePredicate来进行服务实例清单的过滤。这是一个组合过滤条件,构造方法中,以

ZoneAvoidancePredicate为主过滤条件,AvailabilityPredicate为次过滤条件

ZoneAvoidanceRule并没有重写choose()方法,所以遵循父类“先过滤,在轮循”,

过滤条件是CompositePredicate,源码如下

可以看到定义了一个主过滤条件AbstractServerPredicate delegate以及一组次过滤条件列表List fallbacks,

所以它的次过滤列表是可以多个的,

 

posted on 2018-07-23 19:12  持续在更新  阅读(283)  评论(0编辑  收藏  举报

导航