Dubbo中的负载均衡

dubbo中的负载均衡算法:java

  • RandomLoadBalance(其实是权重随机)
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        int length = invokers.size();
        boolean sameWeight = true;
        int[] weights = new int[length];
		// 获取设置的第一个节点的权重
        int firstWeight = this.getWeight((Invoker)invokers.get(0), invocation);
        weights[0] = firstWeight;
        int totalWeight = firstWeight;

        int offset;
        int i;
        // 轮询每个节点的权重
	for(offset = 1; offset < length; ++offset) {
            i = this.getWeight((Invoker)invokers.get(offset), invocation);
			// 存放全部节点的权重
            weights[offset] = i;
            totalWeight += i; // 统计权重之和
           //判断每一个节点的权重是否一致
            if (sameWeight && i != firstWeight) {
                sameWeight = false;
            }
        }
	  
          if (totalWeight > 0 && !sameWeight) {
           // 从总权重中返回一个随机值
             offset = ThreadLocalRandom.current().nextInt(totalWeight);
	     
		  /**
		   *  判断offset落在哪一个权重范围内
		   *  例若有三个节点 A[weight=2],B[weight=3],C[weight=5]
		   * 假设offset = 1
		   * 那么:
		   * 1 - 2 < 0 因此获得A节点
		   * 假设offset = 2
		   * 那么:
		   * 2-2 = 0 、 0 - 3 < 0 获得B节点
		   * 一样假设offset = 5
		   * 那么:
		   * 5 - 2 = 3 > 0 、 3 - 3 = 0 、0 - 5 < 0 获得C节点
		   **/
            for(i = 0; i < length; ++i) {
                offset -= weights[i];
                if (offset < 0) {
                    return (Invoker)invokers.get(i);
                }
            }
        }
	// 若是每一个节点权重都一致的话则随机返回一个节点
        return (Invoker)invokers.get(ThreadLocalRandom.current().nextInt(length));
    }
  • LeastActiveLoadBalance(最小活跃数)

最小活跃数负载均衡算法对应LeastActiveLoadBalance。活跃调用数越小,代表该服务提供者效率越高,单位时间内可处理更多的请求,此时应优先将请求分配给该服务提供者。算法

  • RoundRobinLoadBalance(权重轮询)
  • ConsistentHashLoadBalance(一致性hash)
protected int getWeight(Invoker<?> invoker, Invocation invocation) {
    //获取权重值,默认为100
    int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), "weight",100);
    if (weight > 0) {
        //服务提供者启动时间戳
        long timestamp = invoker.getUrl().getParameter("remote.timestamp", 0L);
        if (timestamp > 0L) {
            //当前时间-启动时间=运行时长
            int uptime = (int) (System.currentTimeMillis() - timestamp);
            //获取服务预热时间 默认10分钟 
            int warmup = invoker.getUrl().getParameter("warmup", 600000 );
            //若是服务运行时间小于预热时间,即服务启动未到达10分钟
            if (uptime > 0 && uptime < warmup) {
                //从新计算服务权重
                weight = calculateWarmupWeight(uptime, warmup, weight);
            }
        }
    }
    return weight;
}
相关文章
相关标签/搜索