写点什么

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

作者:洛神灬殇
  • 2023-07-01
    江苏
  • 本文字数:4772 字

    阅读完需:约 16 分钟

【分布式技术专题】「分布式技术架构」实践见真知,手把手教你如何实现一个属于自己的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 通信技术

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


  • [x] 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 通信技术

  • [x] 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,不同平台和不同语言之间的通信就更加容易实现,同时也使得系统具有更好的可伸缩性和可维护性。

发布于: 刚刚阅读数: 4
用户头像

洛神灬殇

关注

🏆 InfoQ写作平台-签约作者 🏆 2020-03-25 加入

【个人简介】酷爱计算机科学、醉心编程技术、喜爱健身运动、热衷悬疑推理的“极客达人” 【技术格言】任何足够先进的技术都与魔法无异 【技术范畴】Java领域、Spring生态、MySQL专项、微服务/分布式体系和算法设计等

评论

发布
暂无评论
【分布式技术专题】「分布式技术架构」实践见真知,手把手教你如何实现一个属于自己的RPC框架(架构技术引导篇)_RPC_洛神灬殇_InfoQ写作社区