Seata RPC 模块的重构之路

简介: RPC 模块是我最初研究 Seata 源码开始的地方,因此我对 Seata 的 RPC 模块有过一些深刻研究,在我研究了一番后,发现 RPC 模块中的代码需要进行优化,使得代码更加优雅,交互逻辑更加清晰易懂,本着 “让天下没有难懂的 RPC 通信代码” 的初衷,我开始了 RPC 模块的重构之路。

头图.png

 

RPC 模块是我最初研究 Seata 源码开始的地方,因此我对 Seata 的 RPC 模块有过一些深刻研究,在我研究了一番后,发现 RPC 模块中的代码需要进行优化,使得代码更加优雅,交互逻辑更加清晰易懂,本着 “让天下没有难懂的 RPC 通信代码” 的初衷,我开始了 RPC 模块的重构之路。

这里建议想要深入了解 Seata 交互细节的,不妨从 RPC 模块的源码入手,RPC 模块相当于 Seata 的中枢,Seata 所有的交互逻辑在 RPC 模块中表现得淋漓尽致。

这次 RPC 模块的重构将会使得 Seata 的中枢变得更加健壮和易于解读。

重构继承关系

在 Seata 的旧版本中,RPC 模块的整体结构有点混乱,尤其是在各个类的继承关系上,主要体现在:

  1. 直接在 Remoting 类继承 Netty Handler,使得 Remoting 类与 Netty Handler 处理逻辑耦合在一起。
  2. 客户端和服务端的 Reomting 类继承关系不统一。
  3. RemotingClient 被 RpcClientBootstrap 实现,而 RemotingServer 却被 RpcServer 实现,没有一个独立的 ServerBootstrap,这个看起来关系非常混乱。
  4. 有些接口没必要抽取出来,比如 ClientMessageSender、ClientMessageListener、ServerMessageSender 等接口,因这些接口会增加整体结构继承关系的复杂性。

针对上面发现的问题,在重构过程中我大致做了如下事情:

  1. 将  Netty Handler 抽象成一个内部类放在 Remoting 类中。
  2. 将 RemotingClient 为客户端顶级接口,定义客户端与服务端交互的基本方法,抽象一层 AbstractNettyRemotingClient,下面分别有 RmNettyRemotingClient、TmNettyRemotingClient;将 RemotingServer 为服务端顶级接口,定义服务端与客户端交互的基本方法,实现类 NettyRemotingServer。
  3. 同时将 ClientMessageSender、ClientMessageListener、ServerMessageSender 等接口方法归入到 RemotingClient、RemotingServer 中,由 Reomting 类实现 RemotingClient、RemotingServer,统一 Remoting 类继承关系。
  4. 新建 RemotingBootstrap 接口,客户端和服务端分别实现 NettyClientBootstrap、NettyServerBootstrap,将引导类逻辑从 Reomting 类抽离出来。

在最新的 RPC 模块中的继承关系简单清晰,用如下类关系图表示:

1.png

  1. AbstractNettyRemoting:Remoting 类的最顶层抽象,包含了客户端和服务端公用的成员变量与公用方法,拥有通用的请求方法(文章后面会讲到),Processor 处理器调用逻辑(文章后面会讲到)。
  2. RemotingClient:客户端最顶级接口,定义客户端与服务端交互的基本方法。
  3. RemotingServer:服务端最顶级接口,定义服务端与客户端交互的基本方法。
  4. AbstractNettyRemotingClient:客户端抽象类,继承 AbstractNettyRemoting 类并实现了 RemotingClient 接口。
  5. NettyRemotingServer:服务端实现类,继承 AbstractNettyRemoting 类并实现了 RemotingServer 接口。
  6. RmNettyRemotingClient:Rm 客户端实现类,继承 AbstractNettyRemotingClient 类。
  7. TmNettyRemotingClient:Tm 客户端实现类,继承 AbstractNettyRemotingClient 类。

同时将客户端和服务端的引导类逻辑抽象出来,如下类关系图表示:

2.png

  1. RemotingBootstrap:引导类接口,有 start 和 stop 两个抽象方法。
  2. NettyClientBootstrap:客户端引导实现类。
  3. NettyServerBootstrap:服务端引导实现类。

解耦处理逻辑

解耦处理逻辑即是将 RPC 交互的处理逻辑从 Netty Handler 中抽离出来,并将处理逻辑抽象成一个个 Processor,为什么要这么做呢?我大致讲下现在存在的一些问题:

  1. Netty Handler 与 处理逻辑是糅合在一起的,由于客户端与服务端都共用了一套处理逻辑,因此为了兼容更多的交互,在处理逻辑中你可以看到非常多难以理解的判断逻辑。
  2. 在 Seata 的交互中有些请求是异步处理的,也有一些请求是同步处理的,但是在旧的处理代码逻辑中对同步异步处理的表达非常隐晦,而且难以看明白。
  3. 无法从代码逻辑当中清晰地表达出请求消息类型与对应的处理逻辑关系。
  4. 在 Seata 后面的更新迭代中,如果不将处理处理逻辑抽离出来,这部分代码想要增加新的交互逻辑,将会非常困难。

在将处理逻辑从 Netty Handler 进行抽离之前,我们先梳理一下 Seata 现有的交互逻辑。

  • RM 客户端请求服务端的交互逻辑:

3.png

  • TM 客户端请求服务端的交互逻辑:

4.png

  • 服务端请求 RM 客户端的交互逻辑:

5.png

从以上的交互图中可以清晰地看到了 Seata 的交互逻辑。

客户端总共接收服务端的消息:

1)服务端请求消息

  • BranchCommitRequest、BranchRollbackRequest、UndoLogDeleteRequest

2)服务端响应消息

  • RegisterRMResponse、BranchRegisterResponse、BranchReportResponse、GlobalLockQueryResponse
  • RegisterTMResponse、GlobalBeginResponse、GlobalCommitResponse、GlobalRollbackResponse、GlobalStatusResponse、GlobalReportResponse
  • HeartbeatMessage(PONG)

服务端总共接收客户端的消息:

1)客户端请求消息

  • RegisterRMRequest、BranchRegisterRequest、BranchReportRequest、GlobalLockQueryRequest
  • RegisterTMRequest、GlobalBeginRequest、GlobalCommitRequest、GlobalRollbackRequest、GlobalStatusRequest、GlobalReportRequest
  • HeartbeatMessage(PING)

2)客户端响应消息

  • BranchCommitResponse、BranchRollbackResponse

基于以上的交互逻辑分析,我们可以将处理消息的逻辑抽象成若干个 Processor,一个 Processor 可以处理一个或者多个消息类型的消息,只需在 Seata 启动时注册将消息类型注册到 ProcessorTable 中即可,形成一个映射关系,这样就可以根据消息类型调用对应的 Processor 对消息进行处理,用如下图表示:

6.png

在抽象 Remoting 类中定一个 processMessage 方法,方法逻辑是根据消息类型从 ProcessorTable 中拿到消息类型对应的 Processor。

这样就成功将处理逻辑从 Netty Handler 中彻底抽离出来了,Handler#channelRead 方法只需要调用 processMessage 方法即可,且还可以灵活根据消息类型动态注册 Processor 到 ProcessorTable 中,处理逻辑的可扩展性得到了极大的提升。

以下是 Processor 的调用流程:

1)客户端

7.png

  • RmBranchCommitProcessor:处理服务端全局提交请求。
  • RmBranchRollbackProcessor:处理服务端全局回滚请求。
  • RmUndoLogProcessor:处理服务端 undo log 删除请求。
  • ClientOnResponseProcessor:客户端处理服务端响应请求,如:BranchRegisterResponse、GlobalBeginResponse、GlobalCommitResponse 等。
  • ClientHeartbeatProcessor:处理服务端心跳响应。

2)服务端

8.png

  • RegRmProcessor:处理 RM 客户端注册请求。
  • RegTmProcessor:处理 TM 客户端注册请求。
  • ServerOnRequestProcessor:处理客户端相关请求,如:BranchRegisterRequest、GlobalBeginRequest、GlobalLockQueryRequest 等。
  • ServerOnResponseProcessor:处理客户端相关响应,如:BranchCommitResponse、BranchRollbackResponse 等。
  • ServerHeartbeatProcessor:处理客户端心跳响应。

下面我以 TM 发起全局事务提交请求为例子,让大家感受下 Processor 在整个交互中所处的位置:

9.png

重构请求方法

在 Seata 的旧版本当中,RPC 的请求方法也是欠缺优雅,主要体现在:

  1. 请求方法过于杂乱无章,没有层次感。
  2. sendAsyncRequest 方法耦合的代码太多,逻辑过于混乱,客户端与服务端都共用了一套请求逻辑,方法中决定是否批量发送是根据参数 address 是否为 null 决定,决定是否同步请求是根据 timeout 是否大于 0 决定,显得极为不合理,且批量请求只有客户端有用到,服务端并没有批量请求,共用一套请求逻辑还会导致服务端异步请求也会创建 MessageFuture 放入 futures 中。
  3. 请求方法名称风格不统一,比如客户端 sendMsgWithResponse,服务端却叫 sendSyncRequest;

针对以上旧版本 RPC 请求方法的各种缺点,我作了以下改动:

  1. 将请求方法统一放入 RemotingClient、RemotingServer 接口当中,并作为顶级接口;
  2. 分离客户端与服务端请求逻辑,将批量请求逻辑单独抽到客户端相关请求方法中,使得是否批量发送不再根据参数 address 是否为 null 决定;
  3. 由于 Seata 自身的逻辑特点,客户端服务端请求方法的参数无法统一,可通过抽取通用的同步/异步请求方法,客户端和服务端根据自身请求逻辑特点实现自身的同步/异步请求逻辑,最后再调用通用的同步/异步请求方法,使得同步/异步请求都有明确的方法,不再根据 timeout 是否大于 0 决定;
  4. 统一请求名称风格。

最终,Seata RPC 的请求方法终于看起来更加优雅且有层次感了。

同步请求:

10.png

异步请求:

11.png

其它

  1. 类目录调整:RPC 模块目录中还有一个 netty 目录,也可以从目录结构中发现 Seata 的初衷是兼容多个 RPC 框架,目前只实现了 netty,但发现 netty 模块中有些类并不 ”netty“,且 RPC 跟目录的类也并不通用,因此需要将相关类的位置进行调整。
  2. 某些类重新命名,比如 netty 相关类包含 「netty」。

最终 RPC 模块看起来是这样的:

12.png

 

 

作者:张乘辉

原文链接

本文为阿里云原创内容,未经允许不得转载

 

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

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

相关文章

被算法“监控”的打工人,这家公司 150 人被算法裁定为“不敬业”

整理 | 禾木木出品 | AI科技大本营(ID:rgznai100)导读近日,一家公司通过 AI 算法裁掉三成员工的消息在网上引起热议。当你上班时突然收到一封邮件显示“效率低下”而要求马上离开公司,你会怎么想呢?据 Game World Obse…

10倍性能提升!DLA SQL推出基于Alluxio的数据湖分析加速功能

简介: 在存储计算分离的场景下,通过网络从远端存储读取数据是一个代价较大的操作,往往会带来性能的损耗。以OSS为例,OSS数据读取延时通常较本地磁盘大很多,同时OSS对单个用户使用的带宽上限做了限制,这都会…

80×60长40米的地笼_石家庄Q345矩形方管 220*80*8方管 华东地区

摘要: 石家庄Q345矩形方管 220*80*8方管 华东地区 无锡征图钢业有限公司是一家以生产矩形钢管为主的方管厂作为专业矩管生产,无缝方管生产企业,矩形钢管生产工艺采用先进的热轧钢管生产线生产,产品销往 ,并部分出口&am…

惠普台式计算机型号怎么看,惠普电脑怎么看型号

惠普电脑怎么看型号如今很多人都已经习惯了使用笔记本电脑,然而又有很多人在用了很长时间后很难第一时间说出所使用笔记本电脑的型号,或者是不知道从哪里查看。下面是jy135小编收集整理的win7电脑配置怎么看,欢迎阅读。如今很多人都已经习惯了…

大促密集,CDN如何保障电商体验如丝般顺滑?

简介: 前不久,阿里云技术天团空降CSDN在线峰会,对核心技术竞争力进行解读。其中,阿里云高级技术专家曾福华分享了《双11: CDN如何保障电商大促如丝般顺滑》的议题。俗话说:养兵千日,用兵一时。每一次的战役…

fullcalendar 显示的时间间隔只有四十五分钟_NHR系列智能显示控制仪表RS485通信中应用...

请点击上方蓝字关注我们!01摘要NHR系列智能显示控制仪表是经过多年开发制造经验而设计生产,集诸多全新功能于一身的新一代智能显示控制仪表。针对现场温度、压力、液位、速度、流量等各种信号进行采集、显示、控制、远传、通讯、打印等处理,构…

高德地图驾车导航内存优化原理与实战

简介: 一般APP只需要关注前台内存过高的系统强杀FOOM,高德地图有不少用户使用后台导航,所以也需要关注后台的内存过高导致的系统强杀BOOM,且后台强杀较前台强杀更为严重。为了提升用户体验,内存治理迫在眉睫。 ​​背景…

向下一代互联网迈进 声网发布全链路加速FPA为互联网增加QoS保障

8月19日,声网Agora举办线上产品发布会,正式发布了“全链路加速FPA(Full-Path Accelerator)”。全链路加速FPA基于声网的软件定义实时网络 SD-RTN™,通过覆盖全球的多点端到端传输优化,全面提升了包含最后一…

平果手机桌面计算机,苹果手机便签记事本怎么在Windows电脑桌面上使用?

原标题:苹果手机便签记事本怎么在Windows电脑桌面上使用?互联网时代的今天,手机和电脑成了现代人必备的常用工具。电脑的话,肯定要选Windows电脑了。毕竟,Windows操作系统上自带有Office办公软件,在它上面办…

这是阿里技术专家对 SRE 和稳定性保障的理解

简介: 在技术工作中,对于产品/基础技术研发和 SRE 两种角色,通常会有基于「是否侧重编码」的理解。对于产品研发转做 SRE ,经常会产生是否要「脱离编码工作」的看法,或者认为是否要「偏离对产品/基础技术的推进」。 前…

Flink 助力美团数仓增量生产

简介: 本文由美团研究员、实时计算负责人鞠大升分享,主要介绍 Flink 助力美团数仓增量生产的应用实践。内容包括:1、数仓增量生产;2、流式数据集成;3、流式数据处理;4、流式 OLAP 应用;5、未来规…

PHP与MySQL外文文献译文和原文_读懂外文文献的秘诀在这里丨49周新闻

搜狗AI合成主播雅妮为你带来【2020年第49周】搜狗新闻联播全 文01搜狗翻译「文档翻译」功能新增“医疗”和“金融”专业术语翻译问君能有几多愁,文献查询挠破头。我本无心空对月,外文翻译更加虐。还在因为如何正确翻译文献资料发愁的朋友,请你…

微软云打印将直接与 OneDrive 集成;全球 90 多家组织敦促苹果放弃引入”儿童安全”功能计划……...

NEWS本周新闻回顾百度发布无人车出行服务平台“萝卜快跑”百度发布无人车出行服务平台“萝卜快跑”。截至2021年上半年,百度Apollo自动驾驶出行服务已累计接待乘客超过40万人次,测试里程超过1400万公里,自动驾驶专利数量超过2900件&#xff0…

「直播实录」中英数据库专家谈:数据库的过去、未来和现在

简介: 数据库是什么?未来的数据会被存在DNA里?数据库里的数据湖是什么? 1月16日,扫地僧做了一场直播,请到我的同事——数据库资深专家封神,和来自帝国理工的高级讲师Thomas Heinis(托…

html dom 知乎,知乎登录页 - 粒子运动效果

简介由于群友的号召,清明时节得空,所以仿知乎登录页面,基于canvas实现了一个粒子(Particle)随机运动的动画效果。DemoDemo源码独立包安装 npm i zhihu-particle --save #使用npm安装复制代码 yarn add zhihu-particle #使用yarn安装复制代码基…

alm系统的使用流程_支持MBSE的企业信息管理系统发展与启示

导读:本文介绍了模型管理与MBSE、产品生命周期管理(PLM)的概念及其之间的关系,分析了不同行业的模型管理现状,提出了模型管理的解决方案与技术方向,最后给出了建设企业信息管理系统的建议,以期为企业信息管理系统支持M…

如何快速部署一个Elasticsearch集群?

作者:无敌码农 来源:无敌码农今天的文章给大家介绍下Elasticsearch这一目前在“搜索”和“分析”领域使用十分广泛的技术组件。并演示如何快速构建一个Elasticsearch集群。Elasticsearch概述Elasticsearch是一款非常强大的开源“搜索”及“分析”引擎。除…

对话阿里云李飞飞:下一代企业级数据库6大技术方向

简介: 对话李飞飞,不仅仅是一次简单的采访,对老鱼来说,也是一种收获,因为,在数据库领域李飞飞拥有敏锐的触角,对数据库发展趋势有着独到的见解和洞察。 题图:DTCC 2020大会专访合影&…

云企业网CEN-TR打造企业级私有网络

简介: 为了满足企业大规模、多样化的组网和网络管理需求,云企业网(CEN)提出了转发路由器TR(Transit Router)的概念。在每个地域内创建一个转发路由器,可以连接大量VPC、VBR,作为您在…

孩子不念书了学计算机,李玫瑾教授:孩子是不是学习的料不用等长大,上幼儿园就能看出来...

读书是通往成功的一个捷径,但却并非所有人都能走这个捷径。虽然家长都不信,也不想相信,但有些孩子就是不适合学习,如果走一些其他的路可能还会有不一样的人生,但要是在学习这一条路上一条走到黑,未来一定不…