Round Robin - wtstengshen/blog-page GitHub Wiki
Round Robin
Round Robin:轮询调度算法,是最长用的负载均衡的算法,在分布式系统中肯定少不了负载均衡的处理,下边就总结一下Round Robin的简单实现;欢迎高手喷;
####1,普通的Round Robin
最普通的轮询调度算法,就是按照一台机器一台机器的进行负载访问;
假如后端有4台server,分别是0,1,2,3;那么轮训调度算法就是按照顺序一台一台的调用,假如一共10次请求,所以后端机器的访问顺序就是0,1,2,3,0,1,2,3,0,1,2
每一台机器都是轮询排队往下调度的,不考虑目前机器的负载情况;其实就是按照0123的方式不断轮询,这个算法写起来也很简单,让一个遍历自增,然后取模就行了;
private AtomicInteger squence = new AtomicInteger(0);
public int nextNoWeight() {
if (squence.intValue() == Integer.MAX_VALUE) {
synchronized (squence) {
if (squence.intValue() == Integer.MAX_VALUE) {
squence = new AtomicInteger(0);
}
}
}
return squence.getAndIncrement() % servers.length;
}
####2,带权重的Round-Robin
带权重的Round Robin就是每台机器的权重不一样,也是轮询算法,但是权重高的被轮询到的次数多;假如有10个请求;机器的权重和访问次数如下:
这个时候就需要考虑权重的问题:
- 权重值从多少开始;
- 如果有两个权重相等,如何处理;
- 选择一个权重值之后,如何选择下一个权重值(权重如何变化);
这里可以借助最大公约数,来判定选中一个权重之后,下一个权重应该是什么;
// 该版本没有考虑多线程并发
public int next() {
// 求最大公约数
int gcd = this.gcd(servers);
// 求权重最大值
int max = this.max(servers);
while (true) {
// 选择的机器,index从-1开始
index = (index + 1) % servers.length;
if (index == 0) {
// currentWeight当前的权重值
currentWeight = currentWeight - gcd;
if (currentWeight <= 0) {
currentWeight = max;
}
}
if (servers[index] >= currentWeight) {
return index;
}
}
}
根据权重进行轮训,需要考虑currentWeight变量的问题,其实就是按照currentWeight变量,来判断当前选择那台机器,使用最大公约数作为每次currentWeight变量的递减步长; 其实,负载均衡的调度算法有很多,就拿LVS来说,有10多种,每一种都有自己的使用范围,下一步准备看一下优秀的开源软件的调度算法是如何写的,本文完;
作者 [@悠悠小竹子][1001]
博客 [iocoding][1002] [1001]: https://github.com/wtstengshen/blog-page [1002]: http://blog.iocoding.com