【分布式技术专题】「分布式技术架构」实践见真知,手把手教你如何实现一个属于自己的RPC框架(架构技术引导篇)

简介: 【分布式技术专题】「分布式技术架构」实践见真知,手把手教你如何实现一个属于自己的RPC框架(架构技术引导篇)

RPC是什么

RPC(Remote  Procedure  Call,远程过程调用)是一种计算机通信协议,它允许一个程序调用另一个程序所在的远程计算机上的子程序(或函数)而不需要自己的代码去处理远程调用的细节。

RPC的应用

RPC技术应用广泛,特别是在分布式系统中。比如,在Web开发中,有时需要从后端服务器请求数据,此时就可以使用RPC进行通信。RPC还可以用于跨语言调用,例如Java程序调用C++程序,也可以用于跨平台通信,例如Windows系统与Linux系统之间的通信。

RPC的技术要点

在RPC的实现中,有多种技术可以选择,如:

  1. RPC框架:实现RPC的一种基础设施,包括协议解析,网络通信,序列化和反序列化,负载均衡等功能。
  2. 序列化和反序列化:将数据结构或对象转换为可以在网络上传输的格式和从网络接收的格式。
  3. 协议:定义消息格式和通信规则。常见的RPC协议包括HTTP,TCP,UDP等。
  4. 负载均衡:在多个服务提供者之间进行负载均衡,减少单个服务提供者的负荷。

RPC的实现案例

除了上面提到的技术,还有一些其他的RPC相关技术,如:

  1. RESTful  API:RESTful是一种设计风格,也可以用于分布式系统中的通信。它包括一组协议和约束条件,可用于提高系统的可伸缩性,可移植性和可靠性。
  2. gRPC:由Google开发的,基于HTTP/2协议的RPC框架,支持多种编程语言和平台。
  3. Thrift:由Facebook开发的,支持多种编程语言和平台的RPC框架,包括Java,Python,C#和Ruby等。
  4. Dubbo:由阿里巴巴开发的,基于Java语言的RPC框架,支持服务治理和容错机制。

自己开发一个RPC框架的实现

通过上面的基本介绍,相信你应该已经大概知道了RPC框架的基本概念和相关的作用了,那么接下来了呢,我们就给予RPC框架的基本原理和功能进行自己开发一个属于我们自己的RPC框架技术,接下来我们就针对于RPC的架构进行一个相关的设计以及实现。


RPC技术方案选择

以下属于RPC技术方案选项的主要整体思维框架图:



我们都知道一句名言,“工欲成其事必先利其器”,针对于RPC框架的技术选项是一个最基础以及重要的环节,那么接下来我们会针对于一下几个方面为大家“铺路”。

  • RPC通信技术
  • RPC设计模式
  • 内部工具选项
  • 技术难点分析

RPC通信技术

介绍一下通信技术有哪些方向可以选择:

  • RPC通信技术
  •  RPC设计模式
  •  内部工具选项
  •  技术难点分析

RPC通信技术实现方案

RPC通信技术属于整个RPC技术的实现“基石”,主要是由于通过tcp协议进行数据传输,从而实现数据的RPC远程调用,如下图所示。



根据上图主要集中于三种IO模式进行实现选择,分别是BIO(同步阻塞)、NIO(同步非阻塞/异步阻塞)以及NIO2,有的时候也称之为AIO(异步阻塞)。

BIO网络通信模型
  • 传统socket-同步阻塞机制
  • Socket:基于TCP协议的网络通信,通过Socket可以实现客户端和服务器之间的数据传输。
  • ServerSocket:用于创建服务器端的Socket对象,监听客户端的连接请求。
NIO网络通信模型
  • 原生 NIO 存在内存循环 bug,并且复杂度过高。
  • Netty 是对 NIO 进行了封装,扩展性和原生性表现最好。
  • Mina 2.0 封装的 NIO 优势体现不出来。
  • Sofa 的相关体系:
  • Sofa-rpc:封装性过于高。
  • Sofa-bolt:扩展性有待加强。
AIO网络通信模型
  • Java API并不成熟
  • 跨平台性不好

在此我们选择的就是就是最稳定并且性能较好的Netty去实现即可。

RPC的设计模式

  •  RPC通信技术
  • RPC设计模式
  •  内部工具选项
  •  技术难点分析


针对于RPC的设计模式,主要针对于以下这几个方面进行分析:


  • 服务端本地方法调用
  • 服务端服务注册体系
  • 服务端调用拦截体系
  • 解析器调用参数解析

服务端本地方法调用

在RPC(远程过程调用)中,服务端方法调用是指客户端调用远程服务的过程。

下面是简要的服务端方法调用的过程:

  1. 定义服务接口:服务端首先需要定义一个接口,以描述提供的服务的方法,包括方法名称、参数和返回类型等。这个接口将用来定义客户端和服务端之间的通信协议。
  2. 实现服务接口:服务端需要实现定义的服务接口,并提供相应的功能逻辑。
  3. 注册服务:服务端将实现的服务接口注册到RPC框架中,以便客户端能够发现这个服务。
  4. 接收请求:服务端开始监听并接收来自客户端的请求。
  5. 解析请求:服务端接收到请求后,需要解析请求中的方法名称和参数等信息。
  6. 调用本地方法:服务端根据解析得到的方法名称,在本地调用对应的方法,并传递请求中的参数。
  7. 执行业务逻辑:本地方法会执行服务端的业务逻辑,并返回结果。
  8. 序列化结果:服务端将方法执行的结果进行序列化,以便网络传输。
  9. 发送响应:服务端将序列化后的结果作为响应发送给客户端。
  10. 等待下一次请求:服务端继续监听并等待下一次的请求。

通过上述过程,服务端实现了接收客户端请求并调用本地方法处理请求的功能,从而提供远程服务。这种方式使得客户端可以像调用本地方法一样调用远程服务,隐藏了底层的网络通信细节,提高了开发效率。



单纯反射机制

Java反射是Java编程语言中的一个特性,它允许程序在运行时动态地获取类的信息、构造对象、调用方法和访问或修改成员变量。通过反射,程序可以以一种通用的方式操作类、对象和方法,而不需要提前了解这些实体的具体细节。

加强版反射技术

ReflectASM是一个基于Java反射的高性能代码生成库,它提供了一种更快速和更直接的方式来访问和操作Java类的字段和方法。ReflectASM通过生成字节码来实现对类的动态访问,避免了反射机制的性能开销和安全性检查。

注意,ReflectASM相对于标准的Java反射机制来说,更加底层和直接,需要开发人员有一定的字节码和底层原理的知识。在使用ReflectASM时,应该注意其使用的上下文和具体的场景,以保证代码的正确性和安全性

方法类型句柄

类型句柄(Type Handle)是一种表示和操作类型信息的机制。Java中的类型句柄可以通过特定的类、接口和反射机制来实现。

  • 类和接口:在Java中,可以通过获取Class对象来获得类型的句柄。例如,可以使用Class.forName("类名")来获取类的类型句柄,或者使用对象.getClass()来获取对象的类型句柄。通过这些类型句柄,可以获取类的名称、父类、接口,以及访问类的成员、方法和构造函数等信息。
  • 反射机制:Java的反射机制提供了一组API来操作类型句柄。通过反射,可以在运行时获取和修改类的结构。例如,可以使用Class.getDeclaredFields()方法来获取类的字段信息,使用Class.getDeclaredMethods()方法来获取类的方法信息,以及使用Class.getDeclaredConstructors()方法来获取类的构造函数信息等。反射机制还提供了动态调用方法、创建对象等功能,可以在运行时动态操作类型。

Java的内省机制

Java中的内省(Introspection)是一种通过分析类的属性、方法和事件等信息来获取和操作类的特性的机制。

Java的内省机制通过Java Bean规范定义,主要是为了支持图形用户界面(GUI)和属性编辑器等工具的开发。内省可以在运行时获取对象的属性、方法和事件等信息,使得程序可以动态地操作对象的特性。

内省机制使用java.beans.Introspector类来分析类的特性,并使用java.beans.PropertyDescriptor类来描述类的属性信息。通过内省机制,可以获取类的属性名、类型、读写方法等信息,从而实现对属性的读写操作。

通过内省机制,我们可以在运行时获取和操作对象的属性信息,实现动态的属性访问和修改。这在Java中广泛应用于图形界面开发、动态配置等场景。但需要注意的是,内省机制会对性能产生一定的影响,因此在性能要求较高的场景下要慎重使用。

服务端服务注册

服务注册远程命名服务的注册中心技术选项,



服务调用拦截器

RPC拦截器栈调用链是在RPC(远程过程调用)中用来处理请求和响应的拦截器链条。它允许在执行真正的RPC方法之前或之后对请求和响应进行拦截和处理。



在RPC服务中,拦截器栈由多个拦截器组成,每个拦截器都可以在处理请求和响应的不同阶段进行相关的操作。当客户端发起RPC请求时,请求会经过拦截器栈中的每个拦截器,直到到达真正的RPC方法。在RPC方法执行完毕后,响应会按照相同的拦截器顺序逆向经过拦截器栈。

拦截器栈调用链的工作方式如下:

  1. 客户端拦截器链:当客户端发送RPC请求时,请求会按照拦截器栈的顺序经过每个拦截器。每个拦截器可以在请求发送之前或之后执行特定的操作。例如,可以在发送请求之前添加认证信息、压缩数据等。
  2. 服务端拦截器链:当服务端接收到RPC请求时,请求会按照拦截器栈的顺序经过每个拦截器。同样地,每个拦截器可以在请求处理之前或之后执行特定的操作。例如,可以在请求处理之前进行权限验证、解密数据等。
  3. 响应拦截器链:当RPC方法执行完毕并生成响应时,响应会按照相同的拦截器顺序逆向经过拦截器栈。每个拦截器可以在响应发送之前或之后执行特定的操作。例如,可以在发送响应之前对数据进行加密、压缩等操作。

通过拦截器栈调用链,我们可以在RPC过程的不同阶段对请求和响应进行拦截和处理,实现一些通用的功能,如认证、日志记录、异常处理等。这种扩展性和灵活性使得RPC拦截器栈调用链在各种分布式系统中得到了广泛的应用。

解析器模式

服务调用参数解析是指在进行服务调用时,对传递的参数进行解析和处理的过程。参数解析是将传递的参数从原始的格式或表示方式转换为程序可理解和使用的形式。



在服务调用中,参数通常以各种不同的形式传递,例如:

  1. URL 参数:参数直接附加在服务的 URL 上,使用特定的名称和值对表示。在接收端,可以通过解析 URL 获取参数值。
  2. 请求体参数:参数作为请求体的一部分发送,可以使用不同的数据格式,如 JSON、XML 或表单数据。在接收端,可以解析请求体获取参数值。
  3. 请求头参数:参数以 HTTP 请求头的形式发送,可以使用自定义的请求头字段来传递参数。在接收端,可以解析请求头获取参数值。
  4. 路径参数:参数直接嵌入在服务 URL 的路径中,允许在 URL 中使用占位符或模板来表示参数。在接收端,可以从路径中提取参数值。

进行参数解析的过程可以包括以下步骤:

  1. 接收请求:服务端接收到请求,并获取请求的原始数据。
  2. 解析参数:根据传递参数的方式和格式,对请求进行相应的解析,提取参数的名称和值。
  3. 参数验证:对解析到的参数进行验证,确保其符合预期的格式和要求。这可以包括验证参数的类型、范围、格式等。
  4. 参数转换:将解析到的参数进行必要的转换,将其转换为程序可理解和使用的形式。例如,将字符串类型的参数转换为数字或日期类型。
  5. 参数处理:根据具体的业务需求,对参数进行相应的处理操作。这可以包括数据的过滤、转换、存储等。

通过参数解析,我们可以将传递的参数转换为程序可以理解和使用的形式,并进行相应的验证和处理。这样可以确保服务调用时参数的正确性和一致性,提高服务的可靠性和稳定性。

内部工具选择

基础工具组件

下面是需要进行支持的RPC技术所需要的基础工具组件:


此处我们不进行详细的介绍和分析,后面系列的章节会认真介绍和说明。

整合框架

Java原生模式是指使用纯Java编写和配置RPC客户端和服务端的方式。

在Java原生模式中,你可以使用Java标准库或第三方库来进行网络通信,序列化和反序列化数据,以及执行远程方法调用。一些常见的Java原生RPC框架包括Apache Thrift、gRPC、Apache Dubbo等。这些框架提供了对RPC相关功能的封装和支持,让你可以快速构建和部署RPC服务。

Spring开发模式是指在Spring框架的基础上使用RPC框架进行开发。Spring框架提供了丰富的功能和特性,包括依赖注入、AOP等,使得开发更加方便和灵活。在Spring开发模式中,你可以使用Spring提供的注解和配置来集成和配置RPC框架。一些常见的支持Spring的RPC框架包括Spring Cloud、Dubbo-Spring-Boot-Starter等。这些框架可以与Spring框架完美集成,让你可以简化RPC服务的开发和管理。

技术难点分析

RPC客户端技术选项方案

RPC扩展性技术选项方案

客户端调用和传输之间是否考虑加入任务队列做二级缓冲,以及解耦,作为调用的速度的控制。


RPC的架构

后面都一一详细的介绍和分析



总的来说,RPC是一项非常重要的技术,可以在分布式系统中方便地完成远程过程调用。有了RPC,不同平台和不同语言之间的通信就更加容易实现,同时也使得系统具有更好的可伸缩性和可维护性。

相关文章
|
11月前
|
人工智能 Kubernetes 数据可视化
Kubernetes下的分布式采集系统设计与实战:趋势监测失效引发的架构进化
本文回顾了一次关键词监测任务在容器集群中失效的全过程,分析了中转IP复用、调度节奏和异常处理等隐性风险,并提出通过解耦架构、动态IP分发和行为模拟优化采集策略,最终实现稳定高效的数据抓取与分析。
234 2
Kubernetes下的分布式采集系统设计与实战:趋势监测失效引发的架构进化
|
数据采集 存储 数据可视化
分布式爬虫框架Scrapy-Redis实战指南
本文介绍如何使用Scrapy-Redis构建分布式爬虫系统,采集携程平台上热门城市的酒店价格与评价信息。通过代理IP、Cookie和User-Agent设置规避反爬策略,实现高效数据抓取。结合价格动态趋势分析,助力酒店业优化市场策略、提升服务质量。技术架构涵盖Scrapy-Redis核心调度、代理中间件及数据解析存储,提供完整的技术路线图与代码示例。
1826 0
分布式爬虫框架Scrapy-Redis实战指南
|
8月前
|
缓存 Cloud Native 中间件
《聊聊分布式》从单体到分布式:电商系统架构演进之路
本文系统阐述了电商平台从单体到分布式架构的演进历程,剖析了单体架构的局限性与分布式架构的优势,结合淘宝、京东等真实案例,深入探讨了服务拆分、数据库分片、中间件体系等关键技术实践,并总结了渐进式迁移策略与核心经验,为大型应用架构升级提供了全面参考。
|
人工智能 自然语言处理 数据可视化
两大 智能体框架 Dify vs Langchain 的全面分析,该怎么选?资深架构师 做一个彻底的解密
两大 智能体框架 Dify vs Langchain 的全面分析,该怎么选?资深架构师 做一个彻底的解密
两大 智能体框架 Dify vs Langchain 的全面分析,该怎么选?资深架构师 做一个彻底的解密
|
8月前
|
人工智能 JavaScript 前端开发
GenSX (不一样的AI应用框架)架构学习指南
GenSX 是一个基于 TypeScript 的函数式 AI 工作流框架,以“函数组合替代图编排”为核心理念。它通过纯函数组件、自动追踪与断点恢复等特性,让开发者用自然代码构建可追溯、易测试的 LLM 应用。支持多模型集成与插件化扩展,兼具灵活性与工程化优势。
680 6
|
8月前
|
存储 NoSQL 前端开发
【赵渝强老师】MongoDB的分布式存储架构
MongoDB分片通过将数据分布到多台服务器,实现海量数据的高效存储与读写。其架构包含路由、配置服务器和分片服务器,支持水平扩展,结合复制集保障高可用性,适用于大规模生产环境。
557 1
|
12月前
|
监控 算法 关系型数据库
分布式事务难题终结:Seata+DRDS全局事务一致性架构设计
在分布式系统中,CAP定理限制了可用性、一致性与分区容错的三者兼得,尤其在网络分区时需做出取舍。为应对这一挑战,最终一致性方案成为常见选择。以电商订单系统为例,微服务化后,原本的本地事务演变为跨数据库的分布式事务,暴露出全局锁失效、事务边界模糊及协议差异等问题。本文深入探讨了基于 Seata 与 DRDS 的分布式事务解决方案,涵盖 AT 模式实践、分片策略优化、典型问题处理、性能调优及高级特性实现,结合实际业务场景提供可落地的技术路径与架构设计原则。通过压测验证,该方案在事务延迟、TPS 及失败率等方面均取得显著优化效果。
603 61
|
监控 Linux 应用服务中间件
Linux多节点多硬盘部署MinIO:分布式MinIO集群部署指南搭建高可用架构实践
通过以上步骤,已成功基于已有的 MinIO 服务,扩展为一个 MinIO 集群。该集群具有高可用性和容错性,适合生产环境使用。如果有任何问题,请检查日志或参考MinIO 官方文档。作者联系方式vx:2743642415。
3944 57
|
10月前
|
人工智能 自然语言处理 JavaScript
Github又一AI黑科技项目,打造全栈架构,只需一个统一框架?
Motia 是一款现代化后端框架,融合 API 接口、后台任务、事件系统与 AI Agent,支持 JavaScript、TypeScript、Python 多语言协同开发。它提供可视化 Workbench、自动观测追踪、零配置部署等功能,帮助开发者高效构建事件驱动的工作流,显著降低部署与运维成本,提升 AI 项目落地效率。
831 0
|
监控 Java 调度
SpringBoot中@Scheduled和Quartz的区别是什么?分布式定时任务框架选型实战
本文对比分析了SpringBoot中的`@Scheduled`与Quartz定时任务框架。`@Scheduled`轻量易用,适合单机简单场景,但存在多实例重复执行、无持久化等缺陷;Quartz功能强大,支持分布式调度、任务持久化、动态调整和失败重试,适用于复杂企业级需求。文章通过特性对比、代码示例及常见问题解答,帮助开发者理解两者差异,合理选择方案。记住口诀:单机简单用注解,多节点上Quartz;若是任务要可靠,持久化配置不能少。
1075 4