策略:RandomLoadBalance,RoundRobinLoadBalance,ConsistentHashLoadBalance,LeastActiveLoadBalance
======= LoadBalance ======
Invokerselect(List> invokers, URL url, Invocation invocation)
======== AbstractLoadBalance =======
weight: 權(quán)重,默認是100锄弱,
uptime:invoker運行時間 = 當(dāng)前系統(tǒng)時間 - invoker運行時間
warmup:invoker預(yù)熱時間,默認是10 * 60 * 1000 = 10min
uptime>0 && uptime < warmup => calculateWarmupWeight
即當(dāng)invoker運行時間小于10min祸憋,則需要計算權(quán)重会宪,運行時間大于10min,權(quán)重直接是默認100
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.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;}
//計算權(quán)重
計算規(guī)則很簡單:uptime/(warmup/weight) = (uptime/warmup) * weight蚯窥,運行時間/默認預(yù)熱時間 * 100也就是說當(dāng)invoker運行時間小于10min時掸鹅,invoker的運行時間越長,其權(quán)重越高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);}
======= RandomLoadBalance ======
選擇算法拦赠,也比較簡單//若權(quán)重都一樣河劝,則隨機選擇其中一個invoker//若權(quán)重不一樣,則在0 - totalWeight 中生成一個隨機數(shù)矛紫,判斷落在哪個片段示意圖:權(quán)重:invoker0=100,invoker1=90,invoker2=80,invoker3=70,則totalWeight=100+90+80+70=340轉(zhuǎn)換成圖表牌里,0-100 區(qū)段屬于invoker0,100-190屬于invoker1 ..若生成隨機數(shù)random=260颊咬,屬于2區(qū)段,則選中invoker2 protectedInvokerdoSelect(List> invokers, URL url, Invocation invocation) {
? ? int length = invokers.size(); // 總個數(shù)
? ? int totalWeight = 0; // 總權(quán)重
? ? boolean sameWeight = true; // 權(quán)重是否都一樣
? ? for (int i = 0; i < length; i++) {
? ? ? ? int weight = getWeight(invokers.get(i), invocation);
? ? ? ? totalWeight += weight; // 累計總權(quán)重
? ? ? ? if (sameWeight && i > 0
? ? ? ? ? ? ? ? && weight != getWeight(invokers.get(i - 1), invocation)) {
? ? ? ? ? ? sameWeight = false; // 計算所有權(quán)重是否一樣
? ? ? ? }
? ? }
? ? if (totalWeight > 0 && ! sameWeight) {
? ? ? ? // 如果權(quán)重不相同且權(quán)重大于0則按總權(quán)重數(shù)隨機
? ? ? ? int offset = random.nextInt(totalWeight);
? ? ? ? // 并確定隨機值落在哪個片斷上
? ? ? ? for (int i = 0; i < length; i++) {
? ? ? ? ? ? offset -= getWeight(invokers.get(i), invocation);
? ? ? ? ? ? if (offset < 0) {
? ? ? ? ? ? ? ? return invokers.get(i);
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? // 如果權(quán)重相同或權(quán)重為0則均等隨機
? ? return invokers.get(random.nextInt(length));
}