记得Nginx用这个实现。
算法步骤:
-
初始化:
- 设置每个节点的权重(weight)。
- 初始化每个节点的当前权重(current_weight)为0。
-
选择过程: a. 对所有节点的当前权重加上其初始权重。 b. 选择当前权重最大的节点。 c. 将被选中节点的当前权重减去所有节点的权重总和。 d. 返回选中的节点。
-
重复步骤2进行下一次选择。
最大公约数(GCD)的作用:
计算GCD的主要目的是优化权重,使算法更加高效。
如果原始权重是 {10, 20, 30},它们的GCD是10。优化后的权重变成 {1, 2, 3}。
- 最大值(max)的作用:
计算最大值主要用于确定算法的循环周期和初始化当前权重。
权重 {1, 2, 3},最大值是3。这意味着在3次选择后,算法会完成一个完整的周期。
public class WeightedRoundRobin {
private int[] weights;
private int[] currentWeights;
private int maxWeight;
private int currentIndex;
private int totalWeight;
public WeightedRoundRobin(int[] weights) {
int gcdWeight = gcd(weights);
this.weights = new int[weights.length];
for (int i = 0; i < weights.length; i++) {
this.weights[i] = weights[i] / gcdWeight;
}
this.currentWeights = new int[weights.length];
this.maxWeight = max(this.weights);
this.currentIndex = -1;
this.totalWeight = 0;
for (int weight : this.weights) {
this.totalWeight += weight;
}
}
private int gcd(int[] numbers) {
int result = numbers[0];
for (int number : numbers) {
result = gcd(result, number);
}
return result;
}
private int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
private int max(int[] numbers) {
int max = numbers[0];
for (int number : numbers) {
if (number > max) {
max = number;
}
}
return max;
}
public int getNextIndex() {
while (true) {
currentIndex = (currentIndex + 1) % weights.length;
if (currentIndex == 0) {
for (int i = 0; i < currentWeights.length; i++) {
currentWeights[i] += weights[i];
}
}
if (currentWeights[currentIndex] >= 1) {
currentWeights[currentIndex] -= totalWeight;
return currentIndex;
}
}
}