Dubbo负载均衡
负载均衡策略与配置细节
Dubbo 内置了 client-based 负载均衡机制,如下是当前支持的负载均衡算法,结合上文提到的自动服务发现机制,消费端会自动使用 Weighted Random LoadBalance 加权随机负载均衡策略
选址调用。
如果要调整负载均衡算法,以下是 Dubbo 框架内置的负载均衡策略:
算法 | 特性 | 备注 | 配置值 |
---|---|---|---|
Weighted Random LoadBalance | 加权随机 | 默认算法,默认权重相同 | random (默认) |
RoundRobin LoadBalance | 加权轮询 | 借鉴于 Nginx 的平滑加权轮询算法,默认权重相同 | roundrobin |
LeastActive LoadBalance | 最少活跃优先 + 加权随机 | 背后是能者多劳的思想 | leastactive |
Shortest-Response LoadBalance | 最短响应优先 + 加权随机 | 更加关注响应速度 | shortestresponse |
ConsistentHash LoadBalance | 一致性哈希 | 确定的入参,确定的提供者,适用于有状态请求 | consistenthash |
P2C LoadBalance | Power of Two Choice | 随机选择两个节点后,继续选择“连接数”较小的那个节点。 | p2c |
Adaptive LoadBalance | 自适应负载均衡 | 在 P2C 算法基础上,选择二者中 load 最小的那个节点 | adaptive |
全局配置
Dubbo 框架的默认策略是 random
加权随机负载均衡。如果要调整策略,只需要设置 loadbalance
相应取值即可,每种负载均衡策略取值请参见文档最上方表格。
为所有服务调用指定全局配置:
dubbo:consumer:loadbalance: roundrobin
接口级配置
可以为每个服务指定不同的负载均衡策略。
在 provider 端设置,作为 consumer 侧默认值
@DubboService(loadbalance = "roundrobin")
public class DemoServiceImpl implements DemoService {}
在 consumer 端设置,具备更高优先级
@DubboReference(loadbalance = "roundrobin")
private DemoService demoService;
方法级配置
也可以指定方法(method)级别的负载均衡策略。
在 Spring Boot 开发模式下,配置 method 级别参数有以下几种方式:
JavaConfig
@Configuration
public class DubboConfiguration {@Beanpublic ServiceBean demoService() {MethodConfig method = new MethodConfig();method.setName("sayHello");method.setLoadbalance("roundrobin");ServiceBean service = new ServiceBean();service.setInterface(DemoService.class);service.setRef(new DemoServiceImpl());service.addMethod(method)return service;}
}
@Autowire
private DemoService demoService;@Configuration
public class DubboConfiguration {@Beanpublic ReferenceBean demoService() {MethodConfig method = new MethodConfig();method.setName("sayHello");method.setLoadbalance("roundrobin");ReferenceBean<DemoService> reference = new ReferenceBean<>();reference.setInterface(DemoService.class);reference.addMethod(method);return reference;}
}
dubbo.properties
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.loadbalance=roundrobin
一致性哈希配置
默认采用第一个参数作为哈希 key,如果需要切换参数,可以指定 hash.arguments
属性
ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<DemoService>();
// ... init
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("hash.arguments", "1");
parameters.put("sayHello.hash.arguments", "0,1");
referenceConfig.setParameters(parameters);
referenceConfig.setLoadBalance("consistenthash");
referenceConfig.get();
自适应负载均衡配置
只需要在 consumer 或 provider 端将 loadbalance
设置为 p2c
或者 adaptive
即可。
自适应负载均衡与限流整体介绍
本文所说的柔性服务主要是指consumer端的负载均衡和provider端的限流两个功能。在之前的dubbo版本中,
- 负载均衡部分更多的考虑的是公平性原则,即consumer端尽可能平等的从provider中作出选择,在某些情况下表现并不够理想。
- 限流部分只提供了静态的限流方案,需要用户对provider端设置静态的最大并发值,然而该值的合理选取对用户来讲并不容易。
我们针对这些存在的问题进行了改进。
负载均衡
使用介绍
在原本的dubbo版本中,有五种负载均衡的方案供选择,他们分别是 Random
、ShortestResponse
、RoundRobin
、LeastActive
和 ConsistentHash
。其中除 ShortestResponse
和 LeastActive
外,其他的几种方案主要是考虑选择时的公平性和稳定性。
对于 ShortestResponse
来说,其设计目的是从所有备选的 provider 中选择 response 时间最短的以提高系统整体的吞吐量。然而存在两个问题:
- 在大多数的场景下,不同provider的response时长没有非常明显的区别,此时该算法会退化为随机选择。
- response的时间长短有时也并不能代表机器的吞吐能力。对于
LeastActive
来说,其认为应该将流量尽可能分配到当前并发处理任务较少的机器上。但是其同样存在和ShortestResponse
类似的问题,即这并不能单独代表机器的吞吐能力。
基于以上分析,我们提出了两种新的负载均衡算法。一种是同样基于公平性考虑的单纯 P2C
算法,另一种是基于自适应的方法 adaptive
,其试图自适应的衡量 provider 端机器的吞吐能力,然后将流量尽可能分配到吞吐能力高的机器上,以提高系统整体的性能。
总体效果
对于负载均衡部分的有效性实验在两个不同的情况下进行的,分别是提供端机器配置比较均衡和提供端机器配置差距较大的情况。
使用方法
Dubbo Java 实现的使用方法 与原本的负载均衡方法相同。只需要在consumer端将"loadbalance"设置为"p2c"或者"adaptive"即可。
代码结构
负载均衡部分的算法实现只需要在原本负载均衡框架内继承 LoadBalance接口即可。
原理介绍
P2C算法
Power of Two Choice 算法简单但是经典,主要思路如下:
- 对于每次调用,从可用的provider列表中做两次随机选择,选出两个节点providerA和providerB。
- 比较providerA和providerB两个节点,选择其“当前正在处理的连接数”较小的那个节点。
adaptive算法
代码的github地址
相关指标
-
cpuLoad
。该指标在provider端机器获得,并通过invocation的attachment传递给consumer端。
-
rt rt为一次rpc调用所用的时间,单位为毫秒。
-
timeout timeout为本次rpc调用超时剩余的时间,单位为毫秒。
-
weight weight是设置的服务权重。
-
currentProviderTime provider端在计算cpuLoad时的时间,单位是毫秒
-
currentTime currentTime为最后一次计算load时的时间,初始化为currentProviderTime,单位是毫秒。
-
multiple
-
lastLatency
-
beta 平滑参数,默认为0.5
-
ewma lastLatency的平滑值
-
inflight inflight为consumer端还未返回的请求的数量。
-
load 对于备选后端机器x来说,若距离上次被调用的时间大于2*timeout,则其load值为0。 否则,
算法实现
依然是基于P2C算法。
- 从备选列表中做两次随机选择,得到providerA和providerB
- 比较providerA和providerB的load值,选择较小的那个。
自适应限流
与负载均衡运行在consumer端不同的是,限流功能运行在provider端。其作用是限制provider端处理并发任务时的最大数量。从理论上讲,服务端机器的处理能力是存在上限的,对于一台服务端机器,当短时间内出现大量的请求调用时,会导致处理不及时的请求积压,使机器过载。在这种情况下可能导致两个问题:
- 由于请求积压,最终所有的请求都必须等待较长时间才能被处理,从而使整个服务瘫痪。
- 服务端机器长时间的过载可能有宕机的风险。
因此,在可能存在过载风险时,拒绝掉一部分请求反而是更好的选择。在之前的 Dubbo 版本中,限流是通过在 provider 端设置静态的最大并发值实现的。但是在服务数量多,拓扑复杂且处理能力会动态变化的局面下,该值难以通过计算静态设置。
基于以上原因,我们需要一种自适应的算法,其可以动态调整服务端机器的最大并发值,使其可以在保证机器不过载的前提下,尽可能多的处理接收到的请求。因此,我们参考相关理论与算法实践基础上,在 Dubbo 框架内实现了两种自适应限流算法,分别是基于启发式平滑的HeuristicSmoothingFlowControl
和基于窗口的 AutoConcurrencyLimier
。
代码的github地址
使用介绍
总体效果
自适应限流部分的有效性实验我们在提供端机器配置尽可能大的情况下进行,并且为了凸显效果,在实验中我们将单次请求的复杂度提高,将超时时间尽可能设置的大,并且开启消费端的重试功能。
使用方法
要确保服务端存在多个节点,并且消费端开启重试策略的前提下,限流功能才能更好的发挥作用。
Dubbo Java 实现的自适应限流开启方法 与静态的最大并发值设置类似,只需在provider端将"flowcontrol"设置为"autoConcurrencyLimier"或者"heuristicSmoothingFlowControl"即可。
代码结构
- FlowControlFilter:在provider端的filter负责根据限流算法的结果来对provider端进行限流功能。
- FlowControl:根据dubbo的spi实现的限流算法的接口。限流的具体实现算法需要继承自该接口并可以通过dubbo的spi方式使用。
- CpuUsage:周期性获取cpu的相关指标
- HardwareMetricsCollector:获取硬件指标的相关方法
- ServerMetricsCollector:基于滑动窗口的获取限流需要的指标的相关方法。比如qps等。
- AutoConcurrencyLimier:自适应限流的具体实现算法。
- HeuristicSmoothingFlowControl:自适应限流的具体实现方法。
原理介绍
HeuristicSmoothingFlowControl
相关指标
-
alpha alpha为可接受的延时的上升幅度,默认为0.3
-
minLatency 在一个时间窗口内的最小的Latency值。
-
noLoadLatency noLoadLatency是单纯处理任务的延时,不包括排队时间。这是服务端机器的固有属性,但是并不是一成不变的。在HeuristicSmoothingFlowControl算法中,我们根据机器CPU的使用率来确定机器当前的noLoadLatency。当机器的CPU使用率较低时,我们认为minLatency便是noLoadLatency。当CPU使用率适中时,我们平滑的用minLatency来更新noLoadLatency的值。当CPU使用率较高时,noLoadLatency的值不再改变。
-
maxQPS 一个时间窗口周期内的QPS的最大值。
-
avgLatency 一个时间窗口周期内的Latency的平均值,单位为毫秒。
-
maxConcurrency 计算得到的当前服务提供端的最大并发值。
算法实现
当服务端收到一个请求时,首先判断CPU的使用率是否超过50%。如果没有超过50%,则接受这个请求进行处理。如果超过50%,说明当前的负载较高,便从HeuristicSmoothingFlowControl算法中获得当前的maxConcurrency值。如果当前正在处理的请求数量超过了maxConcurrency,则拒绝该请求。
相关文章:

Dubbo负载均衡
负载均衡策略与配置细节 Dubbo 内置了 client-based 负载均衡机制,如下是当前支持的负载均衡算法,结合上文提到的自动服务发现机制,消费端会自动使用 Weighted Random LoadBalance 加权随机负载均衡策略 选址调用。 如果要调整负载均衡算法…...

PymuPDF4llm提取pdf文件文字、表格与图片
一、PymuPDF4llm 的功能特点 (一)文本提取 简单易用 PymuPDF4llm 的文本提取功能非常简单易用。只需使用pip install pymupdf4llm进行安装,然后通过import pymupdf4llm导入库,就可以使用md_text pymupdf4llm.to_markdown("…...

20241108通过iperf3确认中科创达的高通CM6125的WIFI的网速【失败】
20241108通过iperf3确认中科创达的高通CM6125的WIFI的网速【失败】 2024/11/8 15:43 由于以太网不能用,那就测试一下WIFI,iperf3链接/测试异常。 一般认为可能的原因有: 1、CM6125开发板的WIFI不带天线,影响性能。 2、CM6125的And…...

Stored procedures in PostgreSQL
select 存储过程,在现了解的情况,还是没有mysql,sqlserver等好写好用。 --postgreSQL 11.0 以下版本 create or replace FUNCTION procInsertSchool (pSchoolId Char(5),pSchoolName VarChar(100),pSchoolTelNo VarChar(8) ) RETURNS void language plp…...

第10章 多表查询
一、什么是多表查询 多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。 前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个关联字段可能建立…...

【基于LSM的ELF文件安全模块设计】参考
《基于LSM的ELF文件安全模块设计文档》 一、设计目标 本设计致力于通过 Linux 安全模块(LSM)构建一个强大而严密的安全防护体系,以实现对 ELF 文件(涵盖可执行文件和动态链接库)的绝对严格的合法性和完整性检查。其核…...

全卷积和全连接
全连接网络和全卷积网络不一样 以下是对两者的正确解释和代码示例: 1. 全连接网络(Fully Connected Network) 全连接网络使用的是 线性层(nn.Linear),也就是我们常说的“全连接层”。它是用于将每一个输入…...

Unity图形学之Shader结构
Unity - Manual: ShaderLab: Legacy Lighting 1.Shader 语言: OpenGL:SGL 跨平台性能非常好 GLSL语言 OpenGL Shader LanguageDX:微软 非跨平台 性能非常好 HLSL语言 High Level Shader LanguageCG:微软和英伟达 联合开发CG …...

离散时间信号的产生
文章目录 前言1.单位冲激序列函数1.2 函数:1.3 实现代码:1.3 调用方式1.4 调用结果 2.单位阶跃序列函数2.1 函数2.2实现代码2.3调用方式2.4调用结果 3.矩形序列3.1函数3.2 实现代码3.3调用方式3.4 调用结果 4.实指数序列4.1函数4.2实现代码4.3调用方式4.…...

物联优化汽车齿轮锻造
在汽车齿轮的锻造工艺中,锻造温度、锻造压力与行程、锻造速度与锤击方式以及热处理工艺等核心参数扮演着举足轻重的角色。这些参数的精准控制与实时监测,对于提升生产效率、确保产品质量、削减生产成本以及推动生产智能化转型具有不可估量的价值。明达技…...

CocosCreator 构建透明背景应用(最新版!!!)
文章目录 透明原理补充设置截图以及代码step1: electron-js mian.jsstep2:ENABLE_TRANSPARENT_CANVASstep3:SOLID_COLOR Transparentstep:4 Build Web phonestep5:package electron-js & change body background-color 效果图补充 透明原理 使用Cocos creator 做桌面应用开…...

使用CentOS宝塔面板docker搭建EasyTier内网穿透服务
0. 前言 EasyTier是一个简单、安全、去中心化的内网穿透 VPN 组网方案,部署方便,支持 MacOS/Linux/Windows/FreeBSD/Android平台,而且作者搭建了一个公共服务器,不想折腾自建服务,可以使用默认的公共服务器地址 tcp:/…...

HTMLCSS: 实现可爱的冰墩墩
效果演示 HTML <div class"wrap"><div class"body"></div><div class"ear"></div><div class"ear rightEar"></div><div class"leftHand"></div><div class"…...

天地图入门|标注|移动飞行|缩放,商用地图替换
“天地图”是国家测绘地理信息局建设的地理信息综合服务网站。集成了来自国家、省、市(县)各级测绘地理信息部门,以及相关政府部门、企事业单位 、社会团体、公众的地理信息公共服务资源,如果做的项目是政府部门、企事业单位尽量选…...

Flutter PC端UI组件库
一、参考Element-ui的设计和交互,构建基于dart的Flutter UI组件库 https://javonhuang.github.io/sky-ui-page/index.html...

NVR小程序接入平台/设备EasyNVR多品牌NVR管理工具/设备汇聚公共资源场景方案全析
随着信息技术的飞速发展,视频监控已经成为现代社会安全管理和业务运营不可或缺的一部分。特别是在公共资源管理方面,视频监控的应用日益广泛,涵盖了智慧城市、智能交通、大型企业以及校园安防等多个领域。NVR小程序接入平台EasyNVR作为一款功…...

干部谈话考察系统:革新传统,精准高效
在干部选拔任用和考核评价的过程中,谈话考察一直是关键环节之一。然而,传统的谈话考察方式却面临着诸多痛点,严重影响了干部考察工作的质量和效率。干部谈话考察系统的出现,为解决这些问题提供了有力的武器。 一、传统谈话考察的…...

反转链表(Leetcode)
反转链表 Leetcode题目链接 题意:翻转一个单链表 🌰: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 在链表本身进行反转即可,不用重新定义链表,这同时浪费时间和空间。 需要采用哑…...

制作游戏外挂的技术栈有哪些
制作游戏外挂是一项涉及多方面技术的复杂任务。这项技术通常被用于在游戏中获得不公平的优势,因此也遭到了大量的讨论与争议。制作外挂需要深厚的编程基础、对系统底层的深入理解以及对具体游戏架构的详细研究。以下是一篇全面的分析文章,旨在揭示制作游…...

python下载pdf
要下载 PDF 文件并将其保存到本地文件夹中,你可以使用 Python 的 requests 库来发送 HTTP 请求,并使用 os 和 io 库来处理文件操作。以下是一个示例代码,展示了如何从给定的 URL 下载 PDF 文件并将其保存到本地 data 文件夹中: i…...

我们来学mysql -- 同时使用 AND 和 OR 查询错误(填坑篇)
AND 和 OR 一同使用问题 现象分析处理扩展 现象 业务上在“锁定”当前零件所在出口国的所有零件时,出现其他国家零件 问题定位 分析 or 切断了操作符之间的连续性,从union角度分析 where k1 Td621 and k1 Vda96 or k3 P00009等同 select * fr…...

关于Websocket
Websocket的基本概念 Websocket是一个“应用层协议”,和HTTP地位是对等的。都是基于传输层的TCP实现的一个广泛被使用的应用层协议。这个协议可以实现服务器主动给客户端推送数据这样的功能。 websocket报文格式 简单了解一下Websocket的报文格式: FIN表…...

vue2 pdf 链接地址打开
vue2 pdf 链接地址打开 1、先下载依赖 “vue-pdf”: “^4.3.0”, “pdfh5”: “^1.4.0”, “pdfjs-dist”: “2.5.207”, 3、打开pdf <template><div id"app"><div id"demo"></div></div> </template> <script&g…...

c# 动态lambda实现二级过滤(多种参数类型)
效果 调用方法 实体类(可以根据需求更换) public class ToolStr50 {public bool isSelected { get; set; }public string toolStr1 { get; set; }public string toolStr2 { get; set; }public string toolStr3 { get; set; }public string toolStr4 { …...

34.Redis事务
1.事务Redis介绍 事务表示一组动作,要么全部执行,要么全部不执行。 例如微博粉丝关注用户,博主粉丝列表增加了用户,粉丝关注列表增加了博主; Redis 提供了简单的事务功能,将一组需要一起执行的命令放到mult…...

认识类和对象
认识类 类是用来对一个实体 ( 对象 ) 来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来干啥) 类中包含的内容称为 类的成员。属性主要是用来描述类的,称之为 类的成员属性或者 类成员变量。方法主要说明类具有哪些功…...

解决echarts桑基图为0时tooltip不显示的问题
关键代码 formatter: function (params) {console.log("params",params)if (params.value 0) {// 如果值为0,返回空字符串,不显示任何内容return params.name : params.value;// return ;} else {// 否则返回标准的格式化信息return par…...

vue3 基础笔记
基础模板语法 //1. 普通文本插值: <p>{{ rawHtml }}</p>//2. v-html 指令:插入 HTML 内容,并希望 Vue 将其视为 HTML 而不是纯文本 <p v-html"rawHtml"></p> let rawHtml <span>这是一个 <b>HTML</…...

Oracle 第30章:最佳实践与案例研究
在《Oracle最佳实践与案例研究》第30章中,我们探讨了实际项目中的经验分享以及解决常见问题的技巧。这一章节旨在通过具体的案例来说明如何在Oracle数据库管理和开发中应用最佳实践。下面我将从几个方面进行详细介绍,并提供一些源代码示例。 1. 性能优化…...

第九周预习报告
文章目录 第九周预习报告学习内容AI 对学习内容的总结章节概述内容总结 对知识总结的反思思维导图基于AI的学习知识点1:系统调用知识点2:进程控制 学习实践过程遇到的问题与解决方式问题1:fork() 调用后,子进程和父进程同时运行导…...