注意:咱们分析的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中实现了,只是性能有点差,框架做者不推荐使用。性能