dubbo|17. Dubbo原理解析-集群&容错之负载均衡

LoadBalance负载均衡, 负责从多个 Invokers中选出具体的一个Invoker用于本次调用,调用过程中包含了负载均衡的算法,调用失败后需要重新选择
LoadBalance接口定义
@SPI(RandomLoadBalance.NAME)
publicinterface LoadBalance{
@Adaptive("loadbalance")
Invoker select(List> invokers,URL url, Invocation invocation)throws RpcException;
}
类注解@SPI说明可以基于Dubbo的扩展机制进行自定义的负责均衡算法实现,默认是随机算法
方法注解@Adaptive说明能够生成设配方法
Select方法设配类通过url的参数选择具体的算法, 在从invokers集合中根据具体的算法选择一个invoker
dubbo|17. Dubbo原理解析-集群&容错之负载均衡
文章图片


【dubbo|17. Dubbo原理解析-集群&容错之负载均衡】
1. RandomLoadBalance: 随机访问策略,按权重设置随机概率,是默认策略
1)获取所有invokers的个数
2)遍历所有Invokers, 获取计算每个invokers的权重,并把权重累计加起来
每相邻的两个invoker比较他们的权重是否一样,有一个不一样说明权重不均等
3)总权重大于零且权重不均等的情况下
按总权重获取随机数offset = random.netx(totalWeight);
遍历invokers确定随机数offset落在哪个片段(invoker上)
dubbo|17. Dubbo原理解析-集群&容错之负载均衡
文章图片





4)权重相同或者总权重为0, 根据invokers个数均等选择
invokers.get(random.nextInt(length))


2. RoundRobinLoadBalance:轮询,按公约后的权重设置轮询比率
1)获取轮询key服务名+方法名
获取可供调用的invokers个数length
设置最大权重的默认值maxWeight=0
设置最小权重的默认值minWeight=Integer.MAX_VALUE
2)遍历所有Inokers,比较出得出maxWeight和minWeight
3)如果权重是不一样的
根据key获取自增序列
自增序列加一与最大权重取模默认得到currentWeigth
遍历所有invokers筛选出大于currentWeight的invokers
设置可供调用的invokers的个数length
4)自增序列加一并与length取模,从invokers获取invoker


3. LeastActiveLoadBalance: 最少活跃调用数, 相同的活跃的随机选择,
活跃数是指调用前后的计数差, 使慢的提供者收到更少的请求,因为越慢的提供者前后的计数差越大。
活跃计数的功能消费者是在ActiveLimitFilter中设置的
dubbo|17. Dubbo原理解析-集群&容错之负载均衡
文章图片





4. 最少活跃的选择过程如下:
1)获取可调用invoker的总个数
初始化最小活跃数,相同最小活跃的个数
相同最小活跃数的下标数组
等等
2)遍历所有invokers, 获取每个invoker的获取数active和权重
找出最小权重的invoker
如果有相同最小权重的inovkers, 将下标记录到数组leastIndexs[]数组中
累计所有的权重到totalWeight变量
3)如果invokers的权重不相等且totalWeight大于0
按总权重随机offsetWeight = random.nextInt(totalWeight)
计算随机值在哪个片段上并返回invoker
dubbo|17. Dubbo原理解析-集群&容错之负载均衡
文章图片



4)如果invokers的权重相等或者totalWeight等于0,均等随机


5. ConsistentHashLoadBalance:一致性hash, 相同参数的请求总是发到同一个提供者,当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。对于一致性哈希算法介绍网上很多,这个给出一篇 http://blog.csdn.net/sparkliang/article/details/5279393供参考,读者请自行阅读ConsistentashLoadBalance中对一致性哈希算法的实现,还是比较通俗易懂的这里不再啰嗦。

    推荐阅读