目前 Dubbo(2.7.4.1版本)实现了 4 种负载均衡策略,UML 类图如下:
这 4 种负载均衡策略都继承自org.apache.dubbo.rpc.cluster.LoadBalance
。
Dubbo 官方也提供了源码导读。
RandomLoadBalance (随机)
随机,按权重设置随机概率(默认的负载均衡策略)。
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
不过这个随机和我们平时说的随机不太一样,是有
weight
(权重) 概念的。
流程图(from 肥朝的博客,表示感谢)):
算法数学分析:
使用了很优雅的带权重随机算法。假设有四个集群节点A,B,C,D,对应的权重分别是1,2,3,4,那么请求到A节点的概率就为1/(1+2+3+4) = 10%.B,C,D节点依次类推为20%,30%,40%。
随机算法核心源码如下:
if (totalWeight > 0 && !sameWeight) {
// 如果权重不都相同,且总权重数大于0,则按总权重数随机
int offset = ThreadLocalRandom.current().nextInt(totalWeight);
// 并确定随机数落在哪个(权重)片段上
for (int i = 0; i < length; i++) {
offset -= weights[i];
if (offset < 0) {
return invokers.get(i);
}
}
}
RoundRobinLoadBalance (轮询)
轮循,按公约后的权重设置轮循比率(权重轮询调度算法)。
缺点:响应慢的 Provider 会堆积请求。
比如:某一个 Provider 响应慢,当请求发到这个 Provider 时就会形成排队,慢慢的,所有请求都会卡在这个 Provider 上。
LeastActiveLoadBalance (最少活跃数)
最少活跃调用数,相同活跃数的随机(活跃数指调用前后计数差)。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
每个服务有一个活跃计数器,会记录该服务当前正在处理的请求数。
流程图(from 肥朝的博客,表示感谢)):
活跃数的变化是在
com.apache.dubbo.rpc.filter.ActiveLimitFilter
中。
ConsistentHashLoadBalance(一致性哈希)
相同参数的请求总是发到同一提供者,当某一台提供者宕机时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
各策略具体解读可参考 Dubbo 官方提供的源码导读。
评论区