前言:在上一篇文章中,我们简单介绍了Ribbon和他的几个重要组件,但是理解一项技能,光知道他的表面是远远不够的,下面,我们就来深入了解一下Ribbon的IRule。
1.IRule 简介
IRule接口代表负载均衡的策略,其中不同的实现类代表了不同的负载策略,一般分为4个子类分支,分别是RandomRule,RoundRobinRule,ClientConfigEnabledRoundRobinRule以及RetryRule。
2.RandomRule
介绍:
RandomRule表示随机策略,他将从服务清单中随机选择一个服务实例。
工作原理:
首先,我们会获取upList与AllList,用AllList的size获取一个随机数,通过这个随机数做为索引,取出upList中的可用实例并进行返回。
3.RoundRobinRule
介绍:
RoundRobinRule表示轮询策略,他将从服务清单中轮询选择一个服务实例。
工作原理:
同样,他将获取可用实例与全部实例。但是这里他会通过AtomicInteger.get()方法获取当前的位置值。
再通过AtomicInteger.compareAndSet(xx,xxx) 比较2个值 ,如果不相同,则后边的值覆盖当前值。
拿到当前值和list的总值进行取模处理,获取本次的索引值。
每次完成操作,当前索引值nextServerCyclicCounter会+1,当nextServerCyclicCounter长度为list的size时,则nextServerCyclicCounter归0,重新开始轮询,轮询操作不满足,最多会等待10次。10次之后就会使用采用父类的choose。
注意:这里为什么要选择10次呢?这里有两个原因:
1. 轮询结果相互影响导致差错,可能你每次请求出来的都是同一个实例或者是一个有问题的实例来回请求。
2. 集群很大时,遍历整个集群判断效率低,我们假设集群中健康的实例要比不健康的多,如果10次找不到,就用父类的choose,这也是一种快速失败机制。
4.ClientConfigEnabledRoundRobinRule
介绍:
ClientConfigEnabledRoundRobinRule是一个很特殊的策略,因为它本身并没有实现什么特殊的处理逻辑,但是他的子类可以实现一些高级策略。当一些本身的策略无法实现某些需求的时候,它也可以做为父类帮助实现某些策略。我们可以挑一个最为典型的策略BestAvailableRule进行解读一下。
5.BestAvailableRule
BestAvailableRule做为ClientConfigEnabledRoundRobinRule的子类,它可以选择出最空闲的实例,也就是请求数最少的实例进行返回。
工作原理:
当loadBalancerStats为空,采用父类的线性轮询,不为空时,则利用loadBalancerStats保存的实例统计信息来选择满足要求的实例,然后遍历负载均衡器中维护的所有满足要求服务实例,过滤掉正在负载的实例,找出其中请求数目最小的实例,进行返回。
6.RetryRule
介绍:
RetryRule是对选定的负载均衡策略加上重试机制。
工作原理:
即在一个配置好的时间段内(默认500ms),当选择实例不成功,则一直尝试使用subRule的方式选择一个可用的实例。如果没有配置负载策略,默认轮询。
下期预告:
好了 ,本篇文章介绍了IRule的几种负载策略,篇幅所限,还剩下3种,分别是WeightedResponseTimeRule,ZoneAvoidanceRule,AvailabilityFilteringRule我们下一篇文章再来细细讲解。