RPC框架整体架构

简介: RPC就是把拦截到的方法参数,转成可以在网络中传输的二进制,并保证在服务提供方能正确地还原出语义,最终实现像调用本地一样地调用远程的目的。

RPC就是把拦截到的方法参数,转成可以在网络中传输的二进制,并保证在服务提供方能正确地还原出语义,最终实现像调用本地一样地调用远程的目的。


1 RPC架构


RPC本质是远程调用,就要通过网络来传输数据。考虑到可靠性,一般默认采用TCP协议。为屏蔽网络传输复杂性,要封装一个单独的数据传输模块收发二进制数据,即传输模块。


用户请求是基于方法调用,方法出入参数都是对象数据,要提前转成二进制,即序列化过程。但只是把方法调用参数的二进制数据传输到服务提供方不够,要在方法调用参数的二进制数据后增加“断句”符,分隔出不同的请求,在两个“断句”符号中间放的内容就是请求的二进制数据,即协议封装。


这两个不同过程目的一样,保证数据在网络中正确传输:


数据能够传输

传输后能正确还原出传输前的语义

可把这两个处理过程放在架构中的同一个模块,统称为协议模块。


还可在协议模块加压缩功能,压缩过程也是对传输的二进制数据进行操作。在实际网络传输过程中,请求数据包在数据链路层可能因太大而被拆分成多个数据包进行传输,为减少被拆分次数,导致整个传输过程时间太长,可在RPC调用时:在方法调用参数或者返回值的二进制数据大于某个阈值的情况下,我们可以通过压缩框架进行无损压缩,然后在另外一端也用同样的压缩算法进行解压,保证数据可还原。


传输和协议两模块是RPC最基础功能,它们使对象可正确传输到服务提供方。但距离RPC目标——实现像调用本地一样调用远程,还缺点。要让这两个模块同时工作,要手写一些黏合代码,但这些代码对使用RPC的研发无意义,且属于一个重复工作,导致使用体验不友好。


要在RPC里把这些细节对研发屏蔽,让他们感觉不到本地调用和远程调用区别。假设有用到Spring,希望RPC能让我们把一个RPC接口定义成一个Spring Bean,并且这个Bean也会统一被Spring Bean Factory管理,可在项目中通过Spring依赖注入到方式引用。这是RPC调用的入口,一般叫Bootstrap模块。


点对点(Point to Point)版本的RPC框架就完成了,一般这种模式的RPC框架为单机版,没有集群能力。


集群能力:针对同一接口有多个服务提供者,但这多个服务提供者对调用方透明,所以在RPC里还要给调用方找到所有的服务提供方,并在RPC里维护好接口跟服务提供者地址的关系,调用方在发起请求时,才能快速找到对应接收地址,即“服务发现”。


但服务发现只解决接口和服务提供方地址映射关系查找,是一种“静态数据”,对RPC来说,每次发送请求时都要用TCP连接的,相对服务提供方IP地址,TCP连接状态瞬息万变,所以RPC框架要有连接管理器去维护TCP连接状态。


有了集群,提供方可能就需要管理好这些服务,RPC就要内置一些服务治理功能,如服务提供方权重的设置、调用授权等一些常规治理手段。而服务调用方需要额外做哪些事?每次调用前,都要根据服务提供方设置的规则,从集群中选择可用的连接,以发送请求。


按分层设计原则,将这些功能模块分为:

112.jpeg



2 可扩展架构


RPC框架怎么支持插件化架构?可将每个功能点抽象成一个接口,将这个接口作为插件契约,然后把这个功能的接口与功能实现分离,并提供接口默认实现。


JDK自带SPI可动态为某接口寻找服务实现,要在Classpath下的META-INF/services目录创建一个以服务接口命名的文件,文件内容就是接口具体实现类。


JDK自带SPI的缺陷

不能按需加载,ServiceLoader加载某接口实现类时,会遍历全部获取,即接口的实现类得全部载入并实例化,造成不必要浪费。


扩展如果依赖其它的扩展,就做不到自动注入和装配,很难和其他框架集成,如扩展里面依赖了一个Spring Bean,原生Java SPI就不支持。


加上插件功能,RPC框架就包含了两大核心体系——核心功能体系与插件体系:


111.jpeg


整个架构就成了一个微内核架构,我们将每个功能点抽象成一个接口,将这个接口作为插件的契约,然后把这个功能的接口与功能的实现分离并提供接口的默认实现。


这样的架构可扩展性好,实现开闭原则,用户方便通过插件扩展实现功能,而且不需要修改核心功能本身


保持了核心包的精简,依赖外部包少,有效减少开发人员引入RPC导致的包版本冲突问题。

3 总结


我们都知道软件开发的过程很复杂,不仅是因为业务需求经常变化,更难的是在开发过程中要保证团队成员的目标统一。我们需要用一种可沟通的话语、可“触摸”的愿景达成目标,我认为这就是软件架构设计的意义。


但仅从功能角度设计出的软件架构并不够健壮,系统不仅要能正确地运行,还要以最低的成本进行可持续的维护,因此我们十分有必要关注系统的可扩展性。只有这样,才能满足业务变化的需求,让系统的生命力不断延伸。


4 FAQ


我是个小测试。使用jmeter进行压力测试。jmeter官网中支持进行定制sampler取样器,写好的jar包放在lib\ext下,再启动jmter时就能看到了。插件化是一个概念,有很多种实现方式,这种也算。


spring的spring.factories这一套也是利用的面向接口编程,感觉比jdk自带的spi也好很多,既然有些问题,那为啥jdk的spi不优化一下?jdk我理解更多是标准。


jdk自带spi一般会有一个接口加载很多实现类的情况吗,因为只能用迭代器遍历,导致只能用类型判断才能找到自己想要的类,这样感觉不够优雅吧,所以我感觉应该都是一个接口配置一个实现类这样就是使用者想要的情况了。那样插件的意义就不存在了!


业务为工业设备联网数据采集,设备种类和型号繁多,产品中通过抽象出一套“驱动”的概念,把每类设备当作一个插件开发,整体产品架构不变,感觉有点这个概念。只是产品还不够大,其他插件体系还不够明确。

目录
相关文章
|
1月前
|
算法 数据挖掘 调度
隐语实训营-第3讲:详解隐私计算框架的架构和技术要点
主要介绍隐语的隐私计算架构,并对每个模块进行拆解、分析,以期望不同使用者找到适合自己的模块,快速入手。
49 4
|
2月前
|
监控 负载均衡 Dubbo
Dubbo 框架揭秘:分布式架构的精髓与魔法【一】
Dubbo 框架揭秘:分布式架构的精髓与魔法【一】
162 0
|
2月前
|
负载均衡 Dubbo Java
Dubbo 3.x:探索阿里巴巴的开源RPC框架新技术
随着微服务架构的兴起,远程过程调用(RPC)框架成为了关键组件。Dubbo,作为阿里巴巴的开源RPC框架,已经演进到了3.x版本,带来了许多新特性和技术改进。本文将探讨Dubbo 3.x中的一些最新技术,包括服务注册与发现、负载均衡、服务治理等,并通过代码示例展示其使用方式。
80 9
|
1月前
|
分布式计算 算法 调度
课3-详解隐私计算框架的架构和技术要点
隐语架构涵盖产品、算法、计算、资源和硬件五层,旨在实现互联互通和跨域管控。产品层包括SecretPad等,简化用户和集成商体验。算法层涉及PSI/PIR、SCQL和联邦学习,提供隐私保护的数据分析和学习。计算层如RayFed、SPU、HEU等,支持分布式计算和密态处理。资源层的KUSCIA用于跨机构任务编排,硬件层涉及FPGA等加速器。互联互通支持黑盒和白盒模式,确保不同平台协作。跨域管控则强调数据流转控制,保护数据权益。
|
12天前
|
敏捷开发 监控 前端开发
深入理解自动化测试框架Selenium的架构与实践
【4月更文挑战第16天】 在现代软件开发过程中,自动化测试已成为确保产品质量和加快迭代速度的关键手段。Selenium作为一种广泛使用的自动化测试工具,其开源、跨平台的特性使得它成为业界的首选之一。本文旨在剖析Selenium的核心架构,并结合实际案例探讨其在复杂Web应用测试中的高效实践方法。通过详细解读Selenium组件间的交互机制以及如何优化测试脚本,我们希望为读者提供深入理解Selenium并有效运用于日常测试工作的参考。
|
1月前
|
算法
隐私计算实训营 第1期-详解隐私计算框架的架构和技术要点
本文简要介绍了隐语技术架构的五层结构:产品层、算法层、计算层、资源层和硬件层。每层分别涉及模块功能、定位和人群画像,旨在使不同角色的用户能轻松理解和使用,降低隐私计算的入门难度。此外,隐语产品设计具有开放性和前瞻性,易于集成。
|
1月前
|
存储 SQL 分布式计算
TiDB整体架构概览:构建高效分布式数据库的关键设计
【2月更文挑战第26天】本文旨在全面概述TiDB的整体架构,深入剖析其关键组件和功能,从而帮助读者理解TiDB如何构建高效、稳定的分布式数据库。我们将探讨TiDB的计算层、存储层以及其他核心组件,并解释这些组件是如何协同工作以实现卓越的性能和扩展性的。通过本文,读者将能够深入了解TiDB的整体架构,为后续的学习和实践奠定坚实基础。
|
1月前
|
消息中间件 缓存 API
|
1月前
|
SQL API 数据处理
新一代实时数据集成框架 Flink CDC 3.0 —— 核心技术架构解析
本文整理自阿里云开源大数据平台吕宴全关于新一代实时数据集成框架 Flink CDC 3.0 的核心技术架构解析。
739 0
新一代实时数据集成框架 Flink CDC 3.0 —— 核心技术架构解析
|
1月前
|
SQL 前端开发 JavaScript
前端后端技术栈分类和整体架构
前端后端技术栈分类和整体架构