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;
}
相關文章
相關標籤/搜索