上一章我们提到了按权轮询算法RoundRobinLoadBalance,这节我们介绍下最少连接数算法LeastActiveLoadBalance。具体算法如下
1 对所有的invokers进行轮询,找出所有active数最小的集合记为 MinList
2 如果length(Minlist) == 1,直接的返回MinList[0],否则转3
3 如果MinList里面所有的invokers的weight相同,那么随机返回一个,不然转4
4 执行按权随机轮询与前面介绍的RandomLoadBalance算法一样。
ok 分析完算法,我们看下源码
public class LeastActiveLoadBalance extends AbstractLoadBalance {
//负载均衡的名称
public static final String NAME = "leastactive";
private final Random random = new Random();
@Override
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
int length = invokers.size(); // Number of invokers
int leastActive = -1; // The least active value of all invokers
int leastCount = 0; // The number of invokers having the same least active value (leastActive)
int[] leastIndexs = new int[length]; // The index of invokers having the same least active value (leastActive)
int totalWeight = 0; // The sum of with warmup weights
int firstWeight = 0; // Initial value, used for comparision
boolean sameWeight = true; // Every invoker has the same weight value?
for (int i = 0; i < length; i++) {
Invoker<T> invoker = invokers.get(i);
//当前invoker的active数
int active = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName()).getActive(); // Active number
//权重数
int afterWarmup = getWeight(invoker, invocation); // Weight
//记录最小active的invoker
if (leastActive == -1 || active < leastActive) { // Restart, when find a invoker having smaller least active value.
leastActive = active; // Record the current least active value
leastCount = 1; // Reset leastCount, count again based on current leastCount
leastIndexs[0] = i; // Reset
totalWeight = afterWarmup; // Reset
firstWeight = afterWarmup; // Record the weight the first invoker
sameWeight = true; // Reset, every invoker has the same weight value?
//如果有多个最小active相同的invoker,进行记录
} else if (active == leastActive) { // If current invoker's active value equals with leaseActive, then accumulating.
leastIndexs[leastCount++] = i; // Record index number of this invoker
totalWeight += afterWarmup; // Add this invoker's weight to totalWeight.
// If every invoker has the same weight?
if (sameWeight && i > 0
&& afterWarmup != firstWeight) {
sameWeight = false;
}
}
}
//如果最小active的invoker只有一个,直接的返回
// assert(leastCount > 0)
if (leastCount == 1) {
// If we got exactly one invoker having the least active value, return this invoker directly.
return invokers.get(leastIndexs[0]);
}
//如果最小active相同的有多个invoker,则按权随机返回
if (!sameWeight && totalWeight > 0) {
// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on totalWeight.
int offsetWeight = random.nextInt(totalWeight) + 1;
// Return a invoker based on the random value.
for (int i = 0; i < leastCount; i++) {
int leastIndex = leastIndexs[i];
offsetWeight -= getWeight(invokers.get(leastIndex), invocation);
if (offsetWeight <= 0)
return invokers.get(leastIndex);
}
}
//如果最小active的invokers的权重都相同,随机返回一个
// If all invokers have the same weight value or totalWeight=0, return evenly.
return invokers.get(leastIndexs[random.nextInt(leastCount)]);
}
}
在上面的代码里面有一句很关键,就是用来就算某个invoker的active数的,如下
int active = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName()).getActive(); // Active number
是个静态方法,使用的RpcStatus来记录的,而这些信息是怎么塞进去的,后面我们分析dubbo的filter的在进行讲解
网友评论