Nginx基于权重的轮询算法实现
Nginx平滑的基于权重轮询算法描述为:
Algorithm is as follows: on each peer selection we increase current_weight of each eligible peer by its weight, select peer with greatest current_weight and reduce its current_weight by total number of weight points distributed among peers.
算法执行2步,选择出1个当前节点:
- 每个节点,用它们的当前值加上它们自己的权重。
- 选择当前值最大的节点为选中节点,并把它的当前值减去所有节点的权重总和。
例如{a:5, b:1, c:1}
三个节点,里面的{5,1,1}
分别代表abc节点的权重。一开始我们初始化三个节点的当前值为{0, 0, 0}
。 选择过程如下表:
轮数 | 选择前的当前权重 | 选择节点 | 选择后的当前权重 |
---|---|---|---|
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, b, c
选择的次数符合5:1:1
,而且权重大的不会被连续选择。7轮选择后, 当前值又回到{0, 0, 0}
,以上操作可以一直循环,一样符合平滑和基于权重。
Go语言实现
|
|
运行输出:
|
|
小结
这里简单做了总结笔记,很多开源项目的基于权重的轮询算法也是参考了此算法,比如著名的Go语言RPC框架https://github.com/smallnest/rpcx。
关于如何证明算法的平滑性,感兴趣的可以阅读下面的参考链接:
- 原文作者:maratrix
- 原文链接:https://maratrix.cn/post/2020/04/14/smooth-weighted-round-robin/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。