简介
RoundRobinLoadBalance是Dubbo中加权轮询负载均衡的实现。所谓轮询是指将请求轮流分配给每台服务器。轮询是简单的无状态负载均衡算法,适用于每台服务器性能相近的场景下。但实际情况,每台服务器的性能是不一样的,我们需要对每台服务器进行加权,以控制每台服务器的负载。经过加权后,每台服务器能够得到的请求数比例,接近或等于他们的权重比。比如服务器 A、B、C 权重比为 5:2:1。那么在8次请求中,服务器 A 将收到其中的5次请求,服务器 B 会收到其中的2次请求,服务器 C 则收到其中的1次请求。
加权轮询的实现,dubbo是有多个版本的。前几个版本都有不同的缺陷,我们直接看最终优化版,参考了Nginx 的平滑加权轮询负载均衡。
每个服务器对应两个权重,分别为 weight 和 currentWeight。其中 weight 是固定的,currentWeight 会动态调整,初始值为0。当有新的请求进来时,遍历服务器列表,让它的 currentWeight 加上自身权重。遍历完成后,找到最大的 currentWeight,并将其减去权重总和,然后返回相应的服务器即可。
举例来说,三台服务器[A,B,C]分别对应权重[5,1,1]。
请求编号 | currentWeight数组 | 选择结果 | 减去权重总和后的currentWeight数组 |
---|---|---|---|
1 | [5, 1, 1] | A | [-2, 1, 1] |
2 | [3, 2, 2] | A | [-4, 2, 2] |
3 | [1, 3, 3] | B | [1, -4, 3] |
4 | [6, -3, 4] | A | [-1, -3, 4] |
5 | [4, -2, 5] | C | [4, -2, -2] |
6 | [9, -1, -1] | A | [2, -1, -1] |
7 | [7, 0, 0] | A | [0, 0, 0] |
如上,经过平滑性处理后,得到的服务器序列为 [A, A, B, A, C, A, A],相比之前的序列 [A, A, A, A, A, B, C],分布性要好一些。初始情况下 currentWeight = [0, 0, 0],第7个请求处理完后,currentWeight 再次变为 [0, 0, 0]。
源码分析
1 | public class RoundRobinLoadBalance extends AbstractLoadBalance { |
总结
以上就是dubbo负载均衡用的方法。实现过程第一次看可能比较绕,多看几次就能看懂精髓。