注意:咱們分析的sofa-rpc版本是5.4.0。java
圖1 RoundRobinLoadBalancer的類繼承圖git
通常的RoundRobin就是輪詢服務提供者。例子:假設服務提供者有S一、S二、S3,那麼第一次選擇S1,第二次則選擇S2,第三次則選擇S3,第四次則選擇S1...這樣不斷輪詢服務提供者。github
下面分析sofa-rpc的RoundRobinLoadBalancer實現,sofa-rpc中與上述例子中的實現有點不一樣。 算法
RoundRobinLoadBalancer的方法doSelect(SofaRequest, List<ProviderInfo>)是該算法的核心,下面咱們重點來分析該方法的實現。doSelect方法中的源碼以下,建議讀者本身從github上down源碼下來本身看源碼。安全
@Override public ProviderInfo doSelect(SofaRequest request, List<ProviderInfo> providerInfos) { String key = getServiceKey(request); // 每一個方法級本身輪詢,互不影響 int length = providerInfos.size(); // 服務提供者總個數 PositiveAtomicCounter sequence = sequences.get(key); if (sequence == null) { sequences.putIfAbsent(key, new PositiveAtomicCounter()); sequence = sequences.get(key); } return providerInfos.get(sequence.getAndIncrement() % length); } private String getServiceKey(SofaRequest request) { StringBuilder builder = new StringBuilder(); builder.append(request.getTargetAppName()).append("#") .append(request.getMethodName()); return builder.toString(); }
sequences個是concurrentHashMap,以下app
ConcurrentMap<String, PositiveAtomicCounter> sequences = new ConcurrentHashMap<String, PositiveAtomicCounter>();
有沒有發現sofa-rpc中的實現與咱們在開始給出的例子有點不同。sofa-rpc中的輪詢算法比開頭例子在維度上更細,sofa-rpc是站在方法method維度上進行的輪詢。框架
1.sofa-rpc爲何站在方法維度實現RoundRobin?若是你能本身提出這個問題,那麼說明你已經看懂了sofa-rpc的RoundRobin算法大體實現。談談我本身的理解:一個服務提供者,提供不少可供調用的方法,某些方法被調用的頻率和次數是高於其它方法的。若是咱們站在方法的維度上實現輪詢,則這種輪詢是更加公平的。能夠看出,sofa-rpc的做者仍是通過認真思考過的。ide
2.上述的全部實現,都沒有考慮服務提供者帶權重的狀況,若是要實現WeightRoundRobin算法(考慮權重的輪詢算法)呢,如何實現?sofa-rpc中實現了,只是性能有點差,框架做者不推薦使用。性能