####负载概述####
- dubbo中的负载均衡机制主要有4种方式,分别是随机,轮训,最少连接数,一致性hash。其中默认情况下,dubbo采用随机方式进行负载。
- dubbo中的负载均衡就是从多个Invoker列表中选择一个可执行的Invoker。集群中的每一个provider都是一个Invoker。
- consumer根据Invocation,url,List三个参数,采用不同的算法进行选择。
####集群类图####
dubbo中的负载类图如下:
- dubbo中的负载均衡采用模板方法方式设计,其中接口LoadBalance定义了选取Ivnvoker的策略,根据Invocation,url,List选择出一个合适的Invoker。其中声明了方法如下:
<T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation)
- AbstractLoadBalance抽象类,实现了select方法,该方法内部又将具体的每种负载策略实现,转接给具体的实现类,即上述类图中的4个实现类。
public abstract class AbstractLoadBalance implements LoadBalance {
static int calculateWarmupWeight(int uptime, int warmup, int weight) {
int ww = (int) ((float) uptime / ((float) warmup / (float) weight));
return ww < 1 ? 1 : (ww > weight ? weight : ww);
}
public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) {
if (invokers == null || invokers.size() == 0)
return null;
if (invokers.size() == 1)
return invokers.get(0);
// 调用模板方法
return doSelect(invokers, url, invocation);
}
// 具体选择哪个Invoker的算法由子类具体实现
protected abstract <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation);
/** 计算每个Invoker的权重,集群中的每一个provider都是一个Invoker,
** 每一个provider可以在服务端设置权重,即consumer在进行选择Inovker时
** 要计算每一个invoker的权重,从而选择出更合适的invoker
**/
protected int getWeight(Invoker<?> invoker, Invocation invocation) {
int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);
if (weight > 0) {
long timestamp = invoker.getUrl().getParameter(Constants.REMOTE_TIMESTAMP_KEY, 0L);
if (timestamp > 0L) {
int uptime = (int) (System.currentTimeMillis() - timestamp);
int warmup = invoker.getUrl().getParameter(Constants.WARMUP_KEY, Constants.DEFAULT_WARMUP);
if (uptime > 0 && uptime < warmup) {
weight = calculateWarmupWeight(uptime, warmup, weight);
}
}
}
return weight;
}
}
- 具体的实现算法类,可以根据源码去具体分析。再这儿就不分析了。