@Override
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
String key = invokers.get(0).getUrl().getServiceKey() + "." + invocation.getMethodName(); //活跃服务提供者集合
ConcurrentMap<String, WeightedRoundRobin> map = methodWeightMap.get(key);
if (map == null) {
methodWeightMap.putIfAbsent(key, new ConcurrentHashMap<String, WeightedRoundRobin>());
map = methodWeightMap.get(key);
}
int totalWeight = 0;
long maxCurrent = Long.MIN_VALUE;
long now = System.currentTimeMillis();
Invoker<T> selectedInvoker = null;
WeightedRoundRobin selectedWRR = null; //找出活跃的权重最大的服务提供者为目标服务提供者
for (Invoker<T> invoker : invokers) {
String identifyString = invoker.getUrl().toIdentityString();
WeightedRoundRobin weightedRoundRobin = map.get(identifyString);
int weight = getWeight(invoker, invocation);
if (weight < 0) {
weight = 0;
}
if (weightedRoundRobin == null) {
weightedRoundRobin = new WeightedRoundRobin();
weightedRoundRobin.setWeight(weight);
map.putIfAbsent(identifyString, weightedRoundRobin);
weightedRoundRobin = map.get(identifyString);
}
if (weight != weightedRoundRobin.getWeight()) {
//weight changed
weightedRoundRobin.setWeight(weight);
}
//每轮询一次,服务提供者的当前权限增长给定步长
long cur = weightedRoundRobin.increaseCurrent();
weightedRoundRobin.setLastUpdate(now); //当前服务提供者权重大于最大权重,最大权重修改为当前服务提供者权重,目标服务提供者设置为当前服务提供者
if (cur > maxCurrent) {
maxCurrent = cur;
selectedInvoker = invoker;
selectedWRR = weightedRoundRobin;
} //用于重新目标服务提供者权重
totalWeight += weight;
} //回收活跃的服务提供者
if (!updateLock.get() && invokers.size() != map.size()) {
if (updateLock.compareAndSet(false, true)) {
try {
// copy -> modify -> update reference
ConcurrentMap<String, WeightedRoundRobin> newMap = new ConcurrentHashMap<String, WeightedRoundRobin>();
newMap.putAll(map);
Iterator<Entry<String, WeightedRoundRobin>> it = newMap.entrySet().iterator();
while (it.hasNext()) {
Entry<String, WeightedRoundRobin> item = it.next();
if (now - item.getValue().getLastUpdate() > RECYCLE_PERIOD) {
it.remove();
}
}
methodWeightMap.put(key, newMap);
} finally {
updateLock.set(false);
}
}
} //目标服务提供者不为空,则将目标服务提供者权重设置为最低:current.addAndGet(-1 * total)
if (selectedInvoker != null) {
selectedWRR.sel(totalWeight);
return selectedInvoker;
} //返回第一个为目标服务提供者
// should not happen here
return invokers.get(0);
}

【Dubbo源码学习】负载均衡算法(2)-轮询算法的实现的更多相关文章

  1. 负载均衡算法,轮询方式 大话设计模式之工厂模式 C#

    负载均衡算法,轮询方式 2018-04-13 17:37 by 天才卧龙, 13 阅读, 0 评论, 收藏, 编辑 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现 ...

  2. Dubbo源码(八) - 负载均衡

    前言 本文基于Dubbo2.6.x版本,中文注释版源码已上传github:xiaoguyu/dubbo 负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡.分摊到多个 ...

  3. Spring Cloud Ribbon 源码分析---负载均衡算法

    上一篇分析了Ribbon如何发送出去一个自带负载均衡效果的HTTP请求,本节就重点分析各个算法都是如何实现. 负载均衡整体是从IRule进去的: public interface IRule{ /* ...

  4. 负载均衡算法: 简单轮询算法, 平滑加权轮询, 一致性hash算法, 随机轮询, 加权随机轮询, 最小活跃数算法(基于dubbo) java代码实现

    直接上干活 /** * @version 1.0.0 * @@menu <p> * @date 2020/11/17 16:28 */ public class LoadBlance { ...

  5. Dubbo源码学习--集群负载均衡算法的实现

    相关文章: Dubbo源码学习文章目录 前言 Dubbo 的定位是分布式服务框架,为了避免单点压力过大,服务的提供者通常部署多台,如何从服务提供者集群中选取一个进行调用, 就依赖Dubbo的负载均衡策 ...

  6. Dubbo源码学习文章目录

    目录 Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 Dubbo源码学习--注册中心分析 Dubbo源码学习--集群负载均衡算法的实现

  7. Dubbo源码学习--服务是如何引用的

    ReferenceBean 跟服务引用一样,Dubbo的reference配置会被转成ReferenceBean类,ReferenceBean实现了InitializingBean接口,直接看afte ...

  8. Dubbo源码学习--注册中心分析

    相关文章: Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 注册中心 关于注册中心,Dubbo提供了多个实现方式,有比较成熟的使用zookeeper 和 redis 的 ...

  9. Dubbo源码学习--服务是如何发布的

    相关文章: Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 ServiceBean ServiceBean 实现ApplicationListener接口监听Conte ...

  10. Dubbo源码学习--优雅停机原理及在SpringBoot中遇到的问题

    Dubbo源码学习--优雅停机原理及在SpringBoot中遇到的问题 相关文章: Dubbo源码学习文章目录 前言 主要是前一阵子换了工作,第一个任务就是解决目前团队在 Dubbo 停机时产生的问题 ...

随机推荐

  1. java HttpClient 忽略证书的信任的实现 MySSLProtocolSocketFactory

    当不需要任何证书访问https时,java中先实现一个MySSLProtocolSocketFactory类忽略证书的信任 package com.tgb.mq.producer.utils; imp ...

  2. Linux中彻底删除Google-Chrome浏览器

    sudo apt-get autoremove --purge google-chrome-stable   卸载chrome后, 删除-/.config/google-chrome,重新安装.

  3. 玩转BLE(2)_使用bluepy扫描BLE的广播数据

    1. 前言 在linux平台下,bluez是一个很不错的软件,提供了很多基于命令行的测试工具,如hciconfig.hcitool.hcidump.bluetoothctl等.利用这些工具,我们可以方 ...

  4. JavaScript获取元素尺寸和大小操作总结(转载)

    一.获取元素的行内样式 var obj = document.getElementById("test"); alert(obj.height + "\n" + ...

  5. React native 中 SectionList用法

    一.代码 import React, { Component } from 'react'; import { AppRegistry, View, Text, SectionList, } from ...

  6. 自动删除Android工程中无用的资源

    开发时间久了, 几个版本迭代之后, 工程中难免留下很多垃圾资源, 造成apk的包很大, 这里介绍一个工具, 可以自动扫描工程中, 没有使用的资源, 然后自动删除: 包括图片, xml, 文本等. 采用 ...

  7. Feign源码解析系列-最佳实践

    前几篇准备写完feign的源码,这篇直接给出Feign的最佳实践,考虑到目前网上还没有一个比较好的实践解释,对于新使用spring cloud的同学会对微服务之间的依赖产生一些迷惑,也会走一些弯路.这 ...

  8. EEG 睡眠 节律 代码

    a1=load('EEG01.txt');[c,r]=size(a1);z=10;%等于几,绘图起点从几开始s=256*z;%绘图起点;还有,这里的256是采样率d=floor(c/256);cn=d ...

  9. 前端框架Angular、react、vue在github上的数据统计-2018-05

    2018年5月31日09:15:45 突然想看看几个前端框架的数量,然后就截图了如下数据: 分析: react关注.收藏.Fork都高vue一些, 但相差不大 angular比较奇葩,收藏只有二者一半 ...

  10. HDU - 6203:ping ping ping (DFS序 贪心)

    pro:给定N+1个点的树,有M对关键点,现在让你破坏最少的点,使得M对关键点不连通. sol:贪心,我们把M对点按照LCA深度排序,每次破坏LCA. 如果一对点(u,v,lca),u-lca-v有点 ...