dubbo中的负载均衡源码-RandomLoadBalance
随机分配
分两种情况
1.无权重
对机器总个数做随机,看随机数落在哪个机器上。比如有ip为a,b,c的三台机器,放在list(invokers)中,那么直接random(list.size())获取到list中机器的下标(0,1,2),随机数是几就是在list中的那台机器上。
2.有权重
对总权重做随机,看随机数落在哪个权重段上。比如三台机器a,b,c 对应的权重分别为 2,1,3。那么总权重totalWeight=2+1+3=6 , 然后对总权重求随机数Random(6),随机值域{0,1,2,3,4,5}. 假设随机数为4,如何算出哪台机器呢? 依次从list中取出机器对应的权重,用 随机权重数 减去 当前机器权重,再判断差值 是否小于零,如果小于了,这台机器就被命中了。否则再去从list中取出下一台机器的权重,去重复上述操作。 假如随机数为4,list中三台机器对应的权重依次为 2,1,3。 第一次操作:取出第一台机器权重2, 4-2=2 > 0,继续取出下一台机器;第二次操作:2-1=1 > 0,继续下一次操作;第三次操作:取出3, 1-3=-2<0。那么第三台机器就是本机随机命中的。
对应源代码
public class RandomLoadBalance extends AbstractLoadBalance {
public static final String NAME = "random";
private final Random random = new Random();
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
int length = invokers.size(); // 总个数
int totalWeight = 0; // 总权重
boolean sameWeight = true; // 权重是否都一样
for (int i = 0; i < length; i++) {
int weight = getWeight(invokers.get(i), invocation);
totalWeight += weight; // 累计总权重
if (sameWeight && i > 0
&& weight != getWeight(invokers.get(i - 1), invocation)) {
sameWeight = false; // 计算所有权重是否一样
}
}
if (totalWeight > 0 && !sameWeight) {
// 如果权重不相同且权重大于0则按总权重数随机
int offset = random.nextInt(totalWeight);
// 并确定随机值落在哪个片断上
for (int i = 0; i < length; i++) {
offset -= getWeight(invokers.get(i), invocation);
if (offset < 0) {
return invokers.get(i);
}
}
}
// 如果权重相同或权重为0则均等随机
return invokers.get(random.nextInt(length));
}
}