RPC异步化原理
深入RPC,更好使用RPC,须从RPC框架整体性能考虑问题。得知道如何提升RPC框架的性能、稳定性、安全性、吞吐量及如何在分布式下快速定位问题。RPC框架如何压榨单机吞吐量?
1 前言
TPS一直上不去,压测时CPU压到40%~50%就再也压不上去,TPS也不提高,咋办?
看业务逻辑,在执行较为耗时的业务逻辑基础上,又同步调用了好几个其它服务。由于这几个服务的耗时较长,导致服务业务逻辑耗时也长,CPU大部分时间都在等待,没得到充分利用,因此CPU利用率和服务吞吐量上不去。
3 RPC调用吞吐量的影响因素
根本原因:由于处理RPC请求较耗时,且CPU大部分时间都在等待而没有去计算,导致CPU利用率不够。好比一个人干活,但他没规划好时间,且长时间都闲着,当然也就完不成太多工作。
导致RPC请求耗时的原因主要在RPC框架本身吗?除非在网络较慢或使用方使用不当,否则大多情况,刨除业务逻辑处理的耗时时间,RPC本身处理请求的效率就算在较差环境也不过ms级。可以说RPC请求耗时大部分是业务耗时,如业务逻辑中有访问DB执行慢SQL的操作。所以,大多情况,影响RPC调用吞吐量原因就是业务逻辑处理慢,CPU大部分时间都在等待资源。
找到根因,对症下药,
3 提升单机吞吐量的方案
响应式开发就是为提升业务处理的吞吐量。提升吞吐量的关键:“异步”。我们的RPC框架要做到完全异步化,实现全异步RPC。试想一下,如果我们每次发送一个异步请求,发送请求过后请求即刻就结束了,之后业务逻辑全部异步执行,结果异步通知,这样可以增加多么可观的吞吐量?
效果不用我说我想你也清楚了。那RPC框架都有哪些异步策略呢?
4 调用端如何异步?
最常用方式就是返回Future对象的Future或入参为Callback对象。Future是最简单的一种异步方式。
发起一次异步请求,并从请求上下文拿到一个Future,之后就可调用Future#get获取结果。
业务逻辑中调用好几个其它服务,若同步调用,假设调用4个服务,每个服务耗时10ms,则业务逻辑执行完至少耗时40ms。采用Future,连发4次异步请求并拿到4个Future,由于异步调用,耗时几乎忽略不计,之后统一调用这几个Future#get。业务逻辑执行完的时间理想情况10ms,耗时整整缩短到原四分之一,即吞吐量可能提升4倍。
5 RPC框架Future异步实现
一次RPC调用本质:调用端向服务端发一条请求消息,服务端收到消息后进行处理,处理后响应给调用端一条响应消息,调用端收到响应消息后再处理,最后将返回值给到动态代理。
对调用端,向服务端发送请求消息与接收服务端响应消息,是两个完全独立过程,大多数情况下都不在一个线程进行。是不是说RPC框架的调用端,对RPC调用的处理逻辑,内部实现就是异步的?是的。
对RPC框架,无论同步 or 异步调用,调用端内部实现都是异步。
调用端发的每条消息都有个唯一标识,调用端向服务端发请求消息前,会先创建一个Future,并存储消息标识与这Future的映射,动态代理所获得返回值最终就是从这Future中获取。当收到服务端响应消息,调用端会根据响应消息的唯一标识,通过映射找到对应Future,将结果注给那个Future,再处理,最后动态代理从Future得到返回值。
- 同步调用,不过是RPC框架在调用端处理逻辑中主动执行Future#get,让动态代理等待返回值
- 异步调用,则是RPC框架没有主动执行Future#get,用户可以从请求上下文得到这Future,自己决定何时执行Future#get
Future示意图
现在你应该很清楚RPC框架是如何实现Future方式的异步了。
6 RPC调用全异步
Future异步是调用端异步的一种方案,那服务端是否需异步,有何实现方案?
RPC服务端接收到请求的二进制消息后,据协议拆包解包,之后将完整消息解码并反序列化,得到入参后,再通过反射执行业务逻辑。生产环境中这些操作都在哪个线程执行?
当然不在一个线程,对二进制消息数据包拆解包的处理是一定在处理网络I/O的线程,若网络通信框架使用Netty,则对二进制包处理在IO线程,而解码与反序列化过程一般也在IO线程处理。
服务端业务逻辑应交给专门业务线程池处理,以防止由于业务逻辑处理过慢而影响网络I/O处理。
我们配置的业务线程池的线程数都有限,业务线程池的线程数一般只会配置到200,因为大多情况下线程数配置到200还不够用,说明业务逻辑该优化。但若碰到特殊业务场景,让配置的业务线程池打满了。
案例
启动一个服务,业务逻辑处理得就是较慢,当访问量逐渐变大,业务线程池很容易打满,吞吐量不理想,这时CPU利用率也很低。咋办?
调大业务线程池的线程数?有更好方案吗?服务端业务处理逻辑异步是个好方案。
调大业务线程池的线程数
勉强可解决这问题,但对RPC框架,往往都有多个服务共用一个线程池情况,即使调大业务线程池,较耗时服务很可能还会影响其它服务。最佳方案:能让业务线程池尽快释放,就需RPC框架支持服务端业务逻辑异步处理。
7 服务端业务逻辑异步方案
较难处理,因为服务端执行完业务逻辑后,要对返回值序列化并编码,将消息响应给调用端,但若是异步处理,业务逻辑触发异步后方法就执行完了,来不及将真正结果进行序列化并编码后响应给调用端。
就要RPC框架提供一种回调方式,让业务逻辑可异步处理,处理完后调用RPC框架回调接口,将最终结果通过回调响应给调用端。
可让RPC框架支持CompletableFuture,实现RPC调用在调用端与服务端之间完全异步,发布一个RPC服务,服务接口定义返回值CompletableFuture对象。
调用过程
- 服务caller发起RPC调用,直接拿到返回值CompletableFuture对象,之后无需任何额外与RPC框架相关操作(如Future方式时需通过请求上下文获取Future的操作),直接就可异步处理
- 在服务端业务逻辑,创建一个返回值CompletableFuture对象,之后服务端真正业务逻辑可在一个线程池中异步处理,业务逻辑完成之后,再调用这CompletableFuture对象的complete方法,完成异步通知
- 调用端在收到服务端发过来的响应后,RPC框架再自动调用调用端拿到的那个返回值CompletableFuture对象的complete方法
- 一次异步调用完成
通过CompletableFuture,RPC框架可真正做到在调用端与服务端间完全异步,同时提升调用端与服务端的两端的单机吞吐量,并且CompletableFuture是Java8原生支持,业务逻辑中没有任何代码入侵性。
8 总结
影响RPC调用的吞吐量主要原因:服务端的业务逻辑比较耗时,并且CPU大部分时间都在等待而没有去计算,导致CPU利用率不够,而提升单机吞吐量的最好办法就是使用异步RPC。
RPC框架的异步策略主要是调用端异步与服务端异步。调用端的异步就是通过Future方式实现异步,调用端发起一次异步请求并且从请求上下文中拿到一个Future,之后通过Future的get方法获取结果,如果业务逻辑中同时调用多个其它的服务,则可以通过Future的方式减少业务逻辑的耗时,提升吞吐量。服务端异步则需要一种回调方式,让业务逻辑可以异步处理,之后调用RPC框架提供的回调接口,将最终结果异步通知给调用端。
另外,我们可以通过对CompletableFuture的支持,实现RPC调用在调用端与服务端之间的完全异步,同时提升两端的单机吞吐量。
其实,RPC框架也可以有其它的异步策略,比如集成RxJava,再比如gRPC的StreamObserver入参对象,但CompletableFuture是Java8原生提供的,无代码入侵性,并且在使用上更加方便。如果是Java开发,让RPC框架支持CompletableFuture可以说是最佳的异步解决方案。
9 FAQ
提升RPC调用吞吐量,还有啥解决方案?
RPC调用方式
sync
默认方式,但这只是『方法』内部同步,在RPC框架内部还是异步处理。
future 方式
消费者得到 future,自行决定何时获取返回结果。
callback 方式
调用端无需同步处理响应结果,可直接返回。最后返回结果在回调线程里异步处理。
oneway 方式
调用端发送请求之后,无需接受响应
Dubbo 2.7后使用 CompletableFuture 提升异步处理能力,支持以上四种方式。
CPU大部分时间都在等待,并未得到充分利用,因此CPU利用率和服务吞吐量当然上不去了。对于这段话,其实线程处于等待状态时,不占用CPU资源。更准确的描述:浪费宝贵线程资源,大量线程处等待状态,可能(不是一定)导致CPU利用率低。
使用异步的时候返回的速度变快了,但是后台所需要的线程数会变少吗?,线程池我理解还是被打满?
异步对于服务提供方来说,RPC线程所要处理的事情就变少了。
压榨单机吞吐量的秘诀是异步化,针对RPC框架异步化分成:
- 调用端,本就是异步化,毕竟通过网络发生完请求消息,后面就是黑盒,此时可选择不让RPC调用端框架拿服务端的响应消息,让调用端应用自行选择何时拿。这样调用端就能发送更多的请求消息,提高吞吐量
- 服务端异步化,核心在于重分利用单机服务端的资源,避免CPU闲置,业务处理线程处于等待状态
若“业务线程池的线程数配置到200”,线程池被打满了,若单纯增加线程数量有用吗?200个线程都处理不了的话,配置到300或500不是只会增加CPU上下文切换时间吗?
可能用处不大,需提高接口性能或者扩容解决。
相关文章:

RPC异步化原理
深入RPC,更好使用RPC,须从RPC框架整体性能考虑问题。得知道如何提升RPC框架的性能、稳定性、安全性、吞吐量及如何在分布式下快速定位问题。RPC框架如何压榨单机吞吐量? 1 前言 TPS一直上不去,压测时CPU压到40%~50%就…...
C# 多窗口切换的实现
1、目的在主窗口中根据不同的按钮选择不同的子窗口显示。2、实现(1)、创建Winform窗体程序,放入SplitContainer控件splitContainer1将窗体分成左右2部分;(2)、在左侧splitContainer1.panel1中放入3个Button…...
【深度学习】RNN
1. 什么是RNN 循环神经网络(Recurrent Neural Network, RNN)是一类以序列(sequence)数据为输入,在序列的演进方向进行递归(recursion)且所有节点(循环单元)按链式连接的递…...
招聘岗位,机会难得
岗位需求 费话不多说,直接上JD: 嵌入式开发工程师: 17:411.计算机、通信等相关专业。 2.熟悉网络基础知识,熟悉802.11a/b/g/n/ac协议,能通过抓包等分析手段排查定位各种wifi相关问题。 3.熟悉路由器主要功能及实现原…...
web打印的几种方法(2023)
在工作中出现web打印的情况是非常多的,其实这也是一个比较烦人的问题,这篇博客整理一下关于Web打印的一些方法或者方式。 1. window.print() 这个方法是用来打印网页的,页面上的其他的元素也会被打印处理,在打印的时候页眉页脚是…...

代码随想录算法训练营day44 | 动态规划之完全背包 518. 零钱兑换 II 377. 组合总和 Ⅳ
day44完全背包基础知识问题描述举个栗子518. 零钱兑换 II1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组377. 组合总和 Ⅳ1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例来推导dp数组完全背包基…...

IntelliJ IDEA 实用插件推荐(包含使用教程)
IntelliJ IDEA 实用插件推荐 背景:电脑重装了,重新下载了最新版的IntelliJ IDEA,感觉默认模式有点枯燥,于是决定从网上下载一些实用美观的插件优化自己以后吃饭的工具,现在推荐的都是目前还能用的(亲身实践…...

WideDeep模型
google提出的Wide&deep模型,将线性模型与DNN很好的结合起来,在提高模型泛化能力的同时,兼顾模型的记忆性。wide&deep这种将线性模型与DNN的并行连接模式,后来称为推荐领域的经典模式,奠定了后面深度学习模型的…...

nacos集群模式+keepalived搭建高可用服务
实际工作中如果nacos这样的核心服务停掉了或者整个服务器宕机了,那整个系统也就gg了,所以像这样的核心服务我们必须要搞个3个或者3个以上的nacos集群部署,实现高可用; 部署高可用版本之前,首先你要会部署单机版的naco…...

吉利「银河」负重突围
吉利控股集团最新公布的数据显示,2022年,吉利控股集团汽车总销量超230万辆,同比增长4.3%。其中,新能源汽车销量超64万辆,同比增长100.3%。 在中国本土市场,2022年吉利集团旗下品牌乘用车总交付量为135.84万…...

QT之图形视图框架概述——Graphics View Framework
QT之图形视图框架概述——Graphics View Framework1. 概述2. 核心类3. 事件传递4. Graphics View 坐标系统5. 参考1. 概述 Graphics View Framework是子Qt 4.2引入的,用来取代之前版本中的QCanvas。Graphics View Framework提拱了用于大量2D图形项的管理和交互的能…...
【SQL开发实战技巧】系列(二十二):数仓报表场景(上) 从分析函数效率一定快吗聊一聊结果集分页和隔行抽样实现方式
系列文章目录 【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事 【SQL开发实战技巧】系列(二):简单单表查询 【SQL开发实战技巧】系列(三):SQL排序的那些事 【SQL开发实战技巧…...

小米无线AR眼镜探索版细节汇总
在MWC 2023期间,小米正式发布了一款无线AR眼镜,虽然还没看过实机,但XDA提前上手体验,我们从中进行总结。首先我要说的是,小米这款眼镜和高通无线AR眼镜参考设计高度重叠,产品卖点几乎一致,只是增…...

Web3中文|Litra:简洁而优美的NFT流动性协议,能给NFT市场带来什么?
2021年,NFT元年2021年,无疑是 NFT 的“元年”。这一年推特创始人的首条推特被拍出250万美元,加密艺术家Beeple的数字作品“First 5000 Days”在佳士得以6900万美元价格成交,无聊猿最高上涨了1800倍。2021年11月,在Goog…...

SSL证书对虚拟主机的用处有哪些?
虚拟主机是指在同一台服务器上,通过不同的域名或IP地址为多个网站提供服务的一种网络主机。而SSL证书则是一种数字证书,它用于加密网站与用户之间的通信,确保数据传输的安全性和完整性。在虚拟主机上,SSL证书有以下几个用处&#…...

SpringCloud之MQ笔记分享
MQ异步通信 初始MQ 同步通信 优点:时效性较强,可以以及得到结果 Feign就属于同步方式–问题: 耦合问题性能下降(中间的等待时间)资源浪费级联失败 异步通信 优点 耦合度低性能提升,吞吐量高故障隔离…...

动态规划背包问题
背包问题的分类 拿到背包问题,最重要的是会归类到哪一种背包问题中,常见的考题里主要是01背包和完全背包,leetcode上连多重背包的题目都没有。实际完全背包问题就是01背包的一种。 对一和零这道题,很多人容易把m看成一个背包,n看成另一个背包,从而当做多重背包。然而这…...
OpenCV4.x图像处理实例-张嘴和闭嘴检测
张嘴和闭嘴检测 在活体验证中,张嘴和闭嘴检测也是一个重要的环节。本文将介绍如何通过检测人脸上唇和下唇的关键点,并计算上唇和下唇的关键点的距离来检测当前人脸状态是否处于张嘴或闭嘴。 张嘴和闭嘴检测主要步骤如下: 第一步,安装依赖库 示例中使用到OpenCV和MediaP…...
软考高级系统分析师系列论文之十二:论实时控制系统与企业信息系统集成在工业控制的常规应用
软考高级系统分析师系列论文之十二:论实时控制系统与企业信息系统集成在工业控制的常规应用 一、摘要二、正文三、总结一、摘要 本文通过“工控组态软件”项目的开发,着重讨论实时系统与信息系统的集成。近年来,国内外的组态软件取得了很大的发展,已广泛应用于企业生产。组…...
蓝桥杯入门即劝退(二十三)货物摆放问题
欢迎关注点赞评论,共同学习,共同进步! ------持续更新蓝桥杯入门系列算法实例-------- 如果你也喜欢Java和算法,欢迎订阅专栏共同学习交流! 你的点赞、关注、评论、是我创作的动力! -------希望我的文章…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...