RPC异步化原理

news/2024/4/25 12:13:26/文章来源:https://blog.csdn.net/qq_33589510/article/details/129251464

深入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上下文切换时间吗?

可能用处不大,需提高接口性能或者扩容解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_74958.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bug的创建和等级

1.如何合理的创建一个bug 创建bug的要素 :问题的版本,发现问题的环境,发现问题的步骤,预取结果,实际结果。 eg: 1.问题的版本:谷歌浏览器108版本 2.发现问题的环境:windows11家庭版…

CHAPTER 2 CentOS的日志系统(日志工具)

日志工具2.1 rsyslogd(syslogd)2.1.1 介绍2.1.2 语法2.1.3 配置文件syslog.conf2.1.4 syslog.conf的配置规则2.1.5 示例2.2 logrotate2.2.1 介绍2.2.2 配置文件2.2.3 示例一2.2.4 示例二2.3 dmesg2.3.1 命令简介2.3.2 使用示例2.4 关于重启/死机的日志2.4.1 last2.4.2 日志查看…

HTML#5表单标签

一. 表单标签介绍表单: 在网页中主要负责数据采集功能,使用<form>标签定义表单表单项: 不同类型的input元素, 下拉列表, 文本域<form> 定义表单<input> 定义表单项,通过typr属性控制输入形式<label> 为表单项定义标注<select> 定义下拉列表<o…

工程机械焊接件焊接结构件三维扫描检测外观质量控制-CASAIM三维扫描检测仪

焊接已发展为制造业中的一种重要的加工方法&#xff0c;广泛应用于航空、航天、冶金、石油、汽车制造以及国防等领域。工程机械焊接件品种繁多、几何形状复杂&#xff0c;焊接件质量的好坏将直接影响到产品的使用寿命长短。对焊缝表面尺寸测量及评定表面焊缝缺陷时&#xff0c;…

叠氮试剂79598-53-1,6-Azidohexanoic Acid,6-叠氮基己酸,末端羧酸可与伯胺基反应

●中文名&#xff1a;6-叠氮基己酸●英文名&#xff1a;6-Azidohexanoic Acid&#xff0c;6-Azidohexanoic COOH●外观以及性质&#xff1a;西安凯新生物科技有限公司供应的6-Azidohexanoic Acid浅黄色或者无色油状&#xff0c;叠氮化物可使用铜催化的Click化学与末端炔烃共轭&…

一文了解 requestAnimationFrame

requestAnimationFrame 的基本使用 requestAnimationFrame 是什么 window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画&#xff0c;并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数&#xff0c;该回调函数会在浏…

腾讯前端二面常考vue面试题(附答案)

虚拟DOM真的比真实DOM性能好吗 首次渲染大量DOM时&#xff0c;由于多了一层虚拟DOM的计算&#xff0c;会比innerHTML插入慢。正如它能保证性能下限&#xff0c;在真实DOM操作的时候进行针对性的优化时&#xff0c;还是更快的。 MVVM的优缺点? 优点: 分离视图&#xff08;V…

MK60DX256VLQ10(256KB)MK60DN256VLQ10 Kinetis K60 MCU FLASH

MK60DX256VLQ10(256KB)MK60DN256VLQ10 Kinetis K60 MCU 32BIT 256KB FLASH 144LQFP【说明】Kinetis K6x MCU系列是一个可扩展的组合&#xff0c;具有不同级别的集成&#xff0c;提供丰富的模拟、通信、定时和控制外设套件&#xff0c;以适应广泛的需求。应用楼宇自动化控制器人…

数仓基础与hive入门

目录1、数仓数据仓库主流开发语言--SQL2、Apache Hive入门2.1 hive定义2.2 为什么使用Hive2.3 Hive和Hadoop关系2.4 场景设计&#xff1a;如何模拟实现Hive功能2.5 Apache Hive架构、组件3、Apache Hive安装部署3.1 metastore配置方式4、Hive SQL语言&#xff1a;DDL建库、建表…

【谷歌grc】recaptcha browser-error 错误

grc 谷歌人机验证错误 https://www.google.com/recaptcha/api/siteverif 返回错误信息 browser-error [{"success": false,"error-codes": ["browser-error"] }]之前都是调通能用的&#xff0c;突然之间就不能用了&#xff0c;查了半天也没有找…

蓝库云|什么是供应链管理?SCM对制造业的重要性

企业在产品的销售经营上&#xff0c;往往不会考量到供应链管理(SCM)的流程规划&#xff0c;但现今的商业环境与以往不同&#xff0c;高度竞争与客户不断提升的期望&#xff0c;藉由做好供应链管理(SCM)&#xff0c;才能更准时的提供优质产品与优良服务&#xff0c;增强企业竞争…

Qt 小项目 图片浏览系统

目录 引言 实现功能&#xff1a; 效果&#xff1a; 实现图片浏览所用知识: 实现流程&#xff1a; 实现环境和UI设计 具体实现 引言 本系统支持&#xff0c;自动播放&#xff0c;左右拖动切换&#xff0c;点击列表切换&#xff0c;点击按钮切换&#xff1b;是一个标准的…

职场性别报告,男女薪酬仍有差距,男性平均薪酬比女性高29.7%

性别是否影响职业&#xff1f;女性求职比男性更加困难&#xff1f;男性薪酬比女性更有优势&#xff1f;人们一说到警察、建筑师通常会想到高大魁梧的男性形象&#xff0c;一说到幼师、护士往往想到的都是温柔的女性形象&#xff0c;职业好似与性别挂钩&#xff1b;女性求职通常…

vue脚手架多页自动化生成实践

前言 在前端开发过程中&#xff0c;常常面对多种业务场景。到目前为止&#xff0c;前端对于不同场景的处理通常会采用不同的渲染方案来组合处理&#xff0c;常见的渲染方案包括&#xff1a;CSR(Client Side Rendering)、SSR(Server Side Rendering)、SSG(Static Site Generati…

LVGL8.3 集成 ST7789V 显示驱动和 CST816T 触摸屏驱动

LVGL8.3 集成 ST7789V 显示驱动和 CTS816S 触摸屏驱动起因效果&#xff08;正常显示&#xff0c;触摸屏可调换X&#xff0c;Y轴&#xff09;使用方式前提操作步骤最后参考起因 LVGL的ESP32 Drivers库中已经包含了大多数显示和触摸芯片的驱动&#xff0c;基本上只需要在MenuCon…

一些无线通信系统模型的概念

一些无线通信系统模型的概念 扩频通信,指的是系统的带宽WWW远大于其信息传输速率R(bits/s)R(bits/s)R(bits/s), 定义展频带因子BeWRB_e \frac{W}{R}Be​RW​, 易知在扩频通信系统中,BeB_eBe​远大于1. 在频率上产生如此大的冗余度,主要是为了减轻无线通信或卫星通信中经常产生…

SpringMVC——响应处理(1)【包含源码分析】

Controller public class JsonReturnController {ResponseBodyGetMapping("/getPet")public Pet getPet(){Pet petnew Pet();pet.setAge(5);pet.setName("lily");return pet;} }项目启动后 浏览器输入 http://localhost:8080/getPet 。 debug DispatcherS…

设备驱动模型--存储技术原理分析笔记 基于2.6.43内核

本文为读书笔记&#xff0c;详细内容参考《存储原理技术分析》1- 驱动模型2- 总线类型2.1- 重要数据结构总线bus_type 和 bus_type_private 互相可以找到对方struct bus_type {const char *name;struct bus_attribute *bus_attrs;struct device_attribute *dev_attrs;s…

BPMN2.0是什么,BPMN能解决企业流程管理中哪些问题?

一、前言&#xff1a; 在任何行业和企业中&#xff0c;一定存在着各式各样的流程&#xff0c;请假流程、报销流程、入职流程、离职流程、出差流程、合同审批流程、出入库流程等等…… 无论是管理者、技术人员还是业务人员&#xff0c;每天肯定也在使用各种流程&#xff0c;但…

Spring彻头彻尾的讲解,按照Spring框架启动流程,逐步剖析问题,不再是大杂烩!

文章目录1. 定义Spring Bean篇1.1 定义Spring Bean的几种方式1.1.1 XML文件定义Spring Bean1.1.2 JavaConfig定义Spring Bean1.1.3 Component注解定义SpringBean1.2 装配Spring Bean的四种常用方式1.2.1 手动装配 XML文件1.2.2 自动装配 XML文件1.2.3 手动装配 JavaConfig文…