【Dubbo源码学习】负载均衡算法(2)-轮询算法的实现
@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)-轮询算法的实现的更多相关文章
- 负载均衡算法,轮询方式 大话设计模式之工厂模式 C#
负载均衡算法,轮询方式 2018-04-13 17:37 by 天才卧龙, 13 阅读, 0 评论, 收藏, 编辑 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现 ...
- Dubbo源码(八) - 负载均衡
前言 本文基于Dubbo2.6.x版本,中文注释版源码已上传github:xiaoguyu/dubbo 负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡.分摊到多个 ...
- Spring Cloud Ribbon 源码分析---负载均衡算法
上一篇分析了Ribbon如何发送出去一个自带负载均衡效果的HTTP请求,本节就重点分析各个算法都是如何实现. 负载均衡整体是从IRule进去的: public interface IRule{ /* ...
- 负载均衡算法: 简单轮询算法, 平滑加权轮询, 一致性hash算法, 随机轮询, 加权随机轮询, 最小活跃数算法(基于dubbo) java代码实现
直接上干活 /** * @version 1.0.0 * @@menu <p> * @date 2020/11/17 16:28 */ public class LoadBlance { ...
- Dubbo源码学习--集群负载均衡算法的实现
相关文章: Dubbo源码学习文章目录 前言 Dubbo 的定位是分布式服务框架,为了避免单点压力过大,服务的提供者通常部署多台,如何从服务提供者集群中选取一个进行调用, 就依赖Dubbo的负载均衡策 ...
- Dubbo源码学习文章目录
目录 Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 Dubbo源码学习--注册中心分析 Dubbo源码学习--集群负载均衡算法的实现
- Dubbo源码学习--服务是如何引用的
ReferenceBean 跟服务引用一样,Dubbo的reference配置会被转成ReferenceBean类,ReferenceBean实现了InitializingBean接口,直接看afte ...
- Dubbo源码学习--注册中心分析
相关文章: Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 注册中心 关于注册中心,Dubbo提供了多个实现方式,有比较成熟的使用zookeeper 和 redis 的 ...
- Dubbo源码学习--服务是如何发布的
相关文章: Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 ServiceBean ServiceBean 实现ApplicationListener接口监听Conte ...
- Dubbo源码学习--优雅停机原理及在SpringBoot中遇到的问题
Dubbo源码学习--优雅停机原理及在SpringBoot中遇到的问题 相关文章: Dubbo源码学习文章目录 前言 主要是前一阵子换了工作,第一个任务就是解决目前团队在 Dubbo 停机时产生的问题 ...
随机推荐
- 不会点git真不行啊.
基本使用: // 进入项目根目录, git init // 接管你的项目文件夹, git status // 查看状态. 绿色已接管,红色未管理 git add . // 添加管理当前目录所有文件及子 ...
- linux之时间设置
date 显示与设置系统时间 %Y year %m moth 月 %d day 日期 %H hour 小时 %M minute 分钟 %S sec 秒 +%F ...
- java利用itext导出pdf
项目中有一功能是导出历史记录,可以导出pdf和excel,这里先说导出pdf.在网上查可以用那些方式导出pdf,用itext比较多广泛. 导出pdf可以使用两种方式,一是可以根据已有的pdf模板,进行 ...
- 浅谈java中的String、StringBuffer、StringBuilder类的区别以及关系
在java中最常见的使用就是对字符串的操作:首先先说一下对字符串的理解:字符串就是一连串字符序列,Java提供了String和StringBuffer两个类来封装字符串,并提供一系列方法来操作字符串对 ...
- python初识模块
sys import sys print(sys.argv) #输出 $ python test.py helo world ['test.py', 'helo', 'world'] # ...
- python 将汉字转换为拼音
xpinyin提供把汉字转为汉语拼音的功能. 安装此模块 pip install xpinyin简单用例: from xpinyin import Pinyin pin = Pinyin() test ...
- Yii easyWechat 开发的时候报错:cURL error 60: SSL certificate problem: unable to get local issuer certificat
最后配置了下php.ini文件curl.cainfo = "D:\AppServ\php5\cacert.pem" //这里填写自己对应的路径并去拷贝了下面链接的代码,自己建了个文 ...
- alsa音频播放过程中的基本概念
以下为 ALSA-Project/FramesPeriods[1] 学习笔记 1, sample_rate: 即每秒进行多少次采样,常见的比如 8000.16000.44100和48000等 2, s ...
- Linux 学习之路 --------ip地址虚拟网络
// ifconfig 查看IP地址 网络信息 我的IP 39.161.136.25 ① 为网卡临时配置IP地址 ifconfig eth0 39.161.136.5 (netmask ...
- Spark 灰度发布在十万级节点上的成功实践 CI CD
原创文章,转载请务必将下面这段话置于文章开头处. 本文转发自技术世界,原文链接 http://www.jasongj.com/spark/ci_cd/ 本文所述内容基于某顶级互联网公司数万节点下 Sp ...