dubbo源码分析-负载均衡算法
来源:互联网 发布:软件下载app 编辑:程序博客网 时间:2024/05/22 17:23
一致性hash(consistent hash)
核心代码:
private Invoker<T> sekectForKey(long hash) { Invoker<T> invoker; Long key = hash; if (!virtualInvokers.containsKey(key)) { SortedMap<Long, Invoker<T>> tailMap = virtualInvokers.tailMap(key); if (tailMap.isEmpty()) { key = virtualInvokers.firstKey(); } else { key = tailMap.firstKey(); } } invoker = virtualInvokers.get(key); return invoker; }
其中virtualInvokers是一棵红黑树,tailMap方法会返回所有hash值大于key的节点,然后取第一个节点即可。其中key值是根据调用的参数md5后再hash计算得出的:
public Invoker<T> select(Invocation invocation) { String key = toKey(invocation.getArguments()); byte[] digest = md5(key); Invoker<T> invoker = sekectForKey(hash(digest, 0)); return invoker; }随机:(Random)
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) { int length = invokers.size(); // 总个数 int totalWeight = 0; // 总权重 boolean sameWeight = true; // 权重是否都一样 for (int i = 0; i < length; i++) { int weight = getWeight(invokers.get(i), invocation); totalWeight += weight; // 累计总权重 if (sameWeight && i > 0 && weight != getWeight(invokers.get(i - 1), invocation)) { sameWeight = false; // 计算所有权重是否一样 } } if (totalWeight > 0 && ! sameWeight) { // 如果权重不相同且权重大于0则按总权重数随机 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); } } } // 如果权重相同或权重为0则均等随机 return invokers.get(random.nextInt(length)); }可以看到是按照权重来路由的,生成一个随机数,看这个随机数落在哪个invoker的权重区间上,那么就会调用哪个invoker。如果权重大,那么执行的机会就会多些。
轮询:(RoundRobin )
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) { String key = invokers.get(0).getUrl().getServiceKey() + "." + invocation.getMethodName(); int length = invokers.size(); // 总个数 int maxWeight = 0; // 最大权重 int minWeight = Integer.MAX_VALUE; // 最小权重 for (int i = 0; i < length; i++) { int weight = getWeight(invokers.get(i), invocation); maxWeight = Math.max(maxWeight, weight); // 累计最大权重 minWeight = Math.min(minWeight, weight); // 累计最小权重 } if (maxWeight > 0 && minWeight < maxWeight) { // 权重不一样 AtomicPositiveInteger weightSequence = weightSequences.get(key); if (weightSequence == null) { weightSequences.putIfAbsent(key, new AtomicPositiveInteger()); weightSequence = weightSequences.get(key); } List<Invoker<?>> listInvoker = weightInvokers.get(key); if (listInvoker == null) { weightInvokers.putIfAbsent(key, new ArrayList<Invoker<?>>()); listInvoker = weightInvokers.get(key); } synchronized(listInvoker){ if(listInvoker.isEmpty()){ // 重新构建 int currentWeight = weightSequence.getAndIncrement() % maxWeight; for (Invoker<T> invoker : invokers) { // 筛选权重值大于等于当前权重基数的Invoker if (getWeight(invoker, invocation) >= currentWeight) { listInvoker.add(invoker); } } } return invokers.remove(0); } } AtomicPositiveInteger sequence = sequences.get(key); if (sequence == null) { sequences.putIfAbsent(key, new AtomicPositiveInteger()); sequence = sequences.get(key); } // 取模轮循 return invokers.get(sequence.getAndIncrement() % length); }上面是修改后的代码,原来的代码有bug。逻辑很简单:基础权重从0开始逐渐增大到最大的权重,计算所有大于基础权重的invoker,并且依次调用。比如说有两个invoker:I1,I2的权重分别是权重4,7。那么I1的权重大于0,1,2,3基础权重,那么会被调用4次,而I2的权重大于0,1,2,3,4,5,6基础权重,所以会被调用7次,这样I1和I2被调用的次数之比就是4:7。
0 0
- dubbo源码分析-负载均衡算法
- dubbo负载均衡算法源码解析
- Dubbo源码学习--集群负载均衡算法的实现
- dubbo负载均衡源码解析balance
- dubbo高级篇-14 负载均衡算法
- Nginx负载均衡算法分析
- Nginx负载均衡算法分析
- Nginx负载均衡算法分析
- Dubbo负载均衡
- dubbo负载均衡策略
- dubbo负载均衡策略
- Dubbo负载均衡
- Dubbo负载均衡
- Dubbo负载均衡策略
- Dubbo的负载均衡
- dubbo负载均衡
- dubbo负载均衡模式
- dubbo负载均衡
- ajax 同步和异步的区别
- 制作一个可以滑动操作的 Table View Cell
- Jprofiler性能测试
- POJ2288 Islands and Bridges
- CPU卡/CPU的分类/CPU卡标准/CPU卡生产流程
- dubbo源码分析-负载均衡算法
- 项目管理者的自我觉察与悦纳
- [C++对象模型][5]堆栈与函数调用
- BUG之路——14.11.11关于指针
- 第11周项目2:求最大公约数
- STM32的读写flash功能在正式项目还是不要用了。?????还是要用的。
- myeclipse关联SDK源码
- solr与.net系列课程(七)solr主从复制
- pdf文件如何免费转换成txt文件