dubbo-cluster
dubbo-cluster 集群模块:将多个服务提供方伪装为一个提供方。
LoadBalance
/**
* random load balance.
*
*/
public class RandomLoadBalance extends AbstractLoadBalance {
public static final String NAME = "random";
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 totalWeight = 0; // The sum of weights
boolean sameWeight = true; // Every invoker has the same weight?
// 计算出所有权重之和
for (int i = 0; i < length; i++) {
int weight = getWeight(invokers.get(i), invocation);
totalWeight += weight; // Sum
if (sameWeight && i > 0
&& weight != getWeight(invokers.get(i - 1), invocation)) {
sameWeight = false;
}
}
// 如果权重不相同,则按照权重调用
if (totalWeight > 0 && !sameWeight) {
// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on totalWeight.
// 计算出偏移量
int offset = random.nextInt(totalWeight);
// Return a invoker based on the random value.
// 返回具体的invoker
for (int i = 0; i < length; i++) {
offset -= getWeight(invokers.get(i), invocation);
if (offset < 0) {
return invokers.get(i);
}
}
}
// If all invokers have the same weight value or totalWeight=0, return evenly.
return invokers.get(random.nextInt(length));
}
}
merger
public class ArrayMerger implements Merger<Object[]> {
public static final ArrayMerger INSTANCE = new ArrayMerger();
@Override
public Object[] merge(Object[]... others) {
if (others.length == 0) {
return null;
}
// 计算所有数组长度之和
int totalLen = 0;
for (int i = 0; i < others.length; i++) {
Object item = others[i];
if (item != null && item.getClass().isArray()) {
totalLen += Array.getLength(item);
} else {
throw new IllegalArgumentException((i + 1) + "th argument is not an array");
}
}
if (totalLen == 0) {
return null;
}
Class<?> type = others[0].getClass().getComponentType();
// 把所有数组合并到一个新数组(result)中
Object result = Array.newInstance(type, totalLen);
int index = 0;
for (Object array : others) {
for (int i = 0; i < Array.getLength(array); i++) {
Array.set(result, index++, Array.get(array, i));
}
}
return (Object[]) result;
}
}