protected<T>Invoker<T>doSelect(List<Invoker<T>>invokers,URLurl,Invocationinvocation){// ... 省略变量定义// 遍历invoker,找到连接数最小的Providerfor(inti=0;i<length;i++){Invoker<T>invoker=invokers.get(i);// 获取Invoker的活跃请求数量intactive=RpcStatus.getStatus(invoker.getUrl(),invocation.getMethodName()).getActive();// 获取默认权重intafterWarmup=getWeight(invoker,invocation);// save for later useweights[i]=afterWarmup;// 比较得到最小连接数的Providerif(leastActive==-1||active<leastActive){leastActive=active;leastCount=1;leastIndexes[0]=i;totalWeight=afterWarmup;firstWeight=afterWarmup;sameWeight=true;}elseif(active==leastActive){leastIndexes[leastCount++]=i;totalWeight+=afterWarmup;if(sameWeight&&afterWarmup!=firstWeight){sameWeight=false;}}}// 连接数相同根据权重随机选,权重相同直接随机选择if(leastCount==1){returninvokers.get(leastIndexes[0]);}if(!sameWeight&&totalWeight>0){intoffsetWeight=ThreadLocalRandom.current().nextInt(totalWeight);for(inti=0;i<leastCount;i++){intleastIndex=leastIndexes[i];offsetWeight-=weights[leastIndex];if(offsetWeight<0){returninvokers.get(leastIndex);}}}returninvokers.get(leastIndexes[ThreadLocalRandom.current().nextInt(leastCount)]);}
@Overrideprotected<T>Invoker<T>doSelect(List<Invoker<T>>invokers,URLurl,Invocationinvocation){// 省略变量定义...// 选出响应时间最短的invokerfor(inti=0;i<length;i++){Invoker<T>invoker=invokers.get(i);RpcStatusrpcStatus=RpcStatus.getStatus(invoker.getUrl(),invocation.getMethodName());SlideWindowDataslideWindowData=methodMap.computeIfAbsent(rpcStatus,SlideWindowData::new);// 计算当前的估计的响应时间longestimateResponse=slideWindowData.getEstimateResponse();intafterWarmup=getWeight(invoker,invocation);weights[i]=afterWarmup;// Same as LeastActiveLoadBalanceif(estimateResponse<shortestResponse){shortestResponse=estimateResponse;shortestCount=1;shortestIndexes[0]=i;totalWeight=afterWarmup;firstWeight=afterWarmup;sameWeight=true;}elseif(estimateResponse==shortestResponse){shortestIndexes[shortestCount++]=i;totalWeight+=afterWarmup;if(sameWeight&&i>0&&afterWarmup!=firstWeight){sameWeight=false;}}}// 更新时间窗口if(System.currentTimeMillis()-lastUpdateTime>SLIDE_PERIOD&&onResetSlideWindow.compareAndSet(false,true)){//reset slideWindowData in async waySlideWindowData.EXECUTOR_SERVICE.execute(()->{methodMap.values().forEach(SlideWindowData::reset);lastUpdateTime=System.currentTimeMillis();onResetSlideWindow.set(false);});}// response相同根据权重随机选,权重相同直接随机选择if(shortestCount==1){returninvokers.get(shortestIndexes[0]);}if(!sameWeight&&totalWeight>0){intoffsetWeight=ThreadLocalRandom.current().nextInt(totalWeight);for(inti=0;i<shortestCount;i++){intshortestIndex=shortestIndexes[i];offsetWeight-=weights[shortestIndex];if(offsetWeight<0){returninvokers.get(shortestIndex);}}}returninvokers.get(shortestIndexes[ThreadLocalRandom.current().nextInt(shortestCount)]);}