RPC架构基本结构和核心技术

news2024/10/6 20:34:17

当你在构建一个分布式系统时,势必需要考虑的一个问题是:如何实现服务与服务之间高效调用?当然,你可以使用Dubbo或Spring Cloud等分布式服务框架来完成这个目标,这些框架帮助我们封装了技术实现的复杂性。那么,假如没有这些框架,而需要自己来实现远程调用,你应该怎么做的?这就需要引入今天讨论的话题:RPC架构。

RPC架构的基本结构

RPC的英文全称为Remote Procedure Call,也就是远程过程调用。我们通常把发生交互关系的两个服务分别称为服务的提供者(Provider)和消费者(Consumer)。简单来说,RPC就是用来实现服务的消费者向提供者发起远程调用的过程,这是RPC最简单的一种表现形式。


接下来,如果我们把上图做一些展开。如果想要实现服务提供者和消费者之间的有效交互,那么两者之间就需要确立与网络通信相关的网络协议以及通信通道。同时,服务的提供者需要把自己的服务调用入口暴露出来,并时刻准备接收来自消费者的请求。这样,RPC架构就演变成这个样子。


在上图中,我们把通信通道和网络协议分别命名为RpcChannel和RpcProtocol,而把提供者接收请求的组件称为RpcAcceptor,把消费者发起请求的组件称为RpcConnector。

然后,对于服务提供者和消费者而言,为了双方能够正常识别所发送的请求和所接收到的响应结果,需要定义统一的契约。我们把这种契约称为远程API,以与本地API进行区别。基于同一套远程API的定义,RPC架构就具备了根据业务来定义通信契约的能力。

类似的,为了我们更好的区分RPC架构中的角色,我们把真正提供业务服务的组件称为RpcServer,而把发起真实客户端请求的组件称为RpcClient。这样,RpcServer负责实现远程API,而RpcClient负责调用远程API。


当然,对于远程API而言,服务提供者和消费者的处理方式显然是不一样的。提供者需要根据消费者的请求来调用RpcServer的具体实现并返回结果,这部分的工作由RpcInvoker来执行,而消费者通过RpcCaller组件对请求进行编码之后发送到服务方并等待结果。

最后,为了降低开发人员的开发难度,让远程调用的执行过程看上去就先在执行本地方法一样,在主流的RPC实现方法中通常都会在客户端添加代理机制的实现组件RpcProxy,从而提供远程服务本地化访问的入口。另一方面,在服务器端,为了更好地控制业务方法执行过程,通常也会引入具备线程管理、超时控制等机制的RpcProcessor组件。


这样,我们对整个RPC架构的演进过程做了详细的描述。可以看到RPC架构有左右对称的两大部分构成,分别代表了一个远程过程调用的客户端和服务器端组件。客户端组件与职责包括:

  1. RpcClient,负责导入(import)由RpcProxy提供的远程接口的代理实现
  2. RpcProxy,远程接口的代理实现,提供远程服务本地化访问的入口
  3. RpcCaller,负责编码和发送调用请求到服务方并等待结果
  4. RpcConnector,负责维持客户端和服务端连接通道和发送数据到服务端

服务端组件与职责包括:

  1. RpcServer,负责导出(export)远程接口
  2. RpcInvoker,负责调用服务端接口的具体实现并返回结果
  3. RpcAcceptor,负责接收客户方请求并返回请求结果
  4. RpcProcessor,负责在服务方控制调用过程,包括管理调用线程池、超时时间等

而客户端和服务器端所共有的组件包括:

  1. RpcProtocol,负责网络传输协议的编码和解码
  2. RpcChannel,网络数据传输通道

这样,我们对一个典型RPC架构中的基本结构和组件已经都了解了,接下来我们再来重点分析想要实现这个架构中所应该具备的技术体系。

RPC架构的技术体系

从RPC架构的基本结构和组件出发,我们可以进一步梳理想要实现RPC架构的技术体系,包括网络通信、序列化、传输协议和远程调用。

网络通信

首当其中的无疑是网络通信。网络通信涉及面很广,RPC架构中的网络通信关注于网络连接、IO模型和可靠性设计。

基于TCP协议的网络连接有两种基本方式,也就是通常所说的长连接和短连接。长连接和短连接的产生在于客户端和服务器端采取的关闭策略,具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择。在RPC框架实现过程中,考虑到性能和服务治理等因素,通常使用长连接进行通信,典型的实现框架就是Dubbo。

关于IO模型,最简单、最基础的就是阻塞式IO(Blocking IO,BIO),BIO要求客户端请求数与服务端线程数一一对应,显然服务端可以创建的线程数会成为系统的瓶颈。因此,在RPC架构中,我们通常都会使用非阻塞IO(Non-blocking IO,NIO)技术来提供性能。

由于存在网络闪断、超时等网络状态相关的不稳定性以及业务系统本身的故障,网络之间的通信必须在发生上述问题时能够快速感知并修复。常见的网络通信保障手段包括链路有效性检测以及断线之后的重连处理等

序列化

想要在网络上传输数据,就需要用到数据序列化技术。序列化的方式有很多,常见的有文本和二进制两大类。XML和JSON是文本类序列化方式的代表,而二进制实现的方案包括Google的Protocol Buffer和Facebook的Thrift等。

性能可能是我们在序列化工具选择过程中最看重的一个指标。性能指标主要包括序列化之后码流大小、序列化/反序列化速度和CPU/内存资源占用。下表中我们列举了目前主流的一些序列化技术:

序列化时间

反序列化时间

大小

压缩后大小

Java 

8654

43787

889

541

hessian

6725

10460

501

313

protocol buffer

2964

1745

239

149

thrift

3177

1949

349

197

json-lib

45788

149741

485

263

jackson

3052

4161

503

271

fastjson

2595

1472

468

251

可以看到在序列化和反序列化时间维度上Alibaba的fastjson具有一定优势,而从空间维度上看,相较其他技术我们可以优先选择Protocol Buffer。

传输协议

在ISO/OSI的7层网络模型中,RPC架构的设计和实现通常会涉及传输层及以上各个层次的相关协议,通常所说的TCP协议就属于传输层,而HTTP协议则位于应用层。传输协议的消息包括消息头和消息体两部分,消息体表示需要传输的业务数据,而消息头用于进行传输控制。图


图7

可以看到每个层次都从上层取得数据,加上消息头信息形成新的数据单元,并将新的数据单元传递给下一层次。

我们可以使用TCP协议和HTTP协议等公共协议作为基本的传输协议构建RPC架构,也可以使用基于HTTP协议的Web Service和RESTful风格设计更加强大和友好的数据传输方式。但大部分RPC框架内部往往使用私有协议进行通信,这样做的主要目的是对共有协议进行精简,从而提升性能。另一方面,出于扩展性的考虑,具备高度定制化的私有协议也比公共协议更加容易实现扩展。这方面典型的示例还是Dubbo框架,它提供了完全自定义的Dubbo协议。

远程调用

RPC本质也是一种服务调用,而服务调用存在两种基本方式,即单向(One Way)模式和请求应答(Request-Response)模式,前者体现为异步操作,而后者一般执行同步操作。

同步调用会造成业务线程阻塞,但开发和管理相对简单。同步调用时序图如下所示,我们可以看到服务线程发送请求到IO线程之后就一直处于等待阶段,直到IO线程完成与网络的读写操作之后被主动唤醒。


使用异步调用的目的在于获取高性能。在实现异步调用过程中,我们通常都会使用到Java中所提供的了Future机制。Future调用可以进一步细分成两种模式,Future-Get模式和Future-Listener模式。Future-Get模式参考下图:


可以看到这种模式下通过主动get结果的方式获取Future结果,而这个get过程是串行的,会造成执行get方法的线程形成阻塞。而Future-Listener模式则不同,在Future-Listener模式中需要创建Listener,当Future结果生成时会唤醒注册到该Future上的Listener对象,从而形成异步回调机制。

除了同步和异步调用之外,还存在并行(Parallel)调用和泛化(Generic)调用等调用方法,虽然也有其特定的应用场景,但对于RPC架构而言并不是主流的调用方式,这里不做具体展开。

可以说,RPC是分布式系统中一项基础设施类的技术体系,但凡涉及到服务与服务之间的交互就需要使用到RPC架构。当你在使用一个分布式框架时,可以尝试使用今天介绍的RPC架构的基本结构和技术体系进行分析,从而加深对这项技术体系的理解。

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

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

相关文章

Spring Boot 整合 JSP

Spring Boot 是一个开源的 Java 框架,用于创建独立、生产级的基于 Spring 框架的应用程序。它简化了基于 Spring 的应用程序的创建和部署过程。JSP(JavaServer Pages)是一种动态网页技术,允许开发者在 HTML 中嵌入 Java 代码。将 …

基于UDP的网络聊天室(多线程实现收和发消息)

要求&#xff1a;1.有新用户登录&#xff0c;其他在线的用户可以收到登录信息 2.有用户群聊&#xff0c;其他在线的用户可以收到群聊信息 3.有用户退出&#xff0c;其他在线的用户可以收到退出信息 4.服务器可以发送系统信息 效果图&#xff1a; service.c #include <head…

内网一键部署k8s-kubeshpere,1.22.12版本

1.引言 本文档旨在指导读者在内网环境中部署 Kubernetes 集群。Kubernetes 是一种用于自动化容器化应用程序部署、扩展和管理的开源平台&#xff0c;其在云原生应用开发和部署中具有广泛的应用。然而&#xff0c;由于一些安全或网络限制&#xff0c;一些组织可能选择在内部网络…

计算机专业课面试常见问题-计算机网络篇

目录 1. 计算机网络分为哪 5 层&#xff1f; 2. TCP 协议简述&#xff1f; 3. TCP 和 UDP 的区别&#xff1f;->不同的应用场景&#xff1f; 4. 从浏览器输入网址到显示页…

论文阅读MVBench: A Comprehensive Multi-modal Video Understanding Benchmark

摘要(Abstract)&#xff1a; 论文介绍了MVBench&#xff0c;这是一个全新的多模态视频理解基准测试&#xff0c;旨在评估多模态大型语言模型&#xff08;MLLMs&#xff09;在视频理解方面的能力。 目前许多基准测试主要集中在静态图像任务的空间理解上&#xff0c;而忽视了动…

云计算【第一阶段(21)】引导过程与服务控制

目录 一、linux操作系统引导过程 1.1、开机自检 1.2、MBR引导 1.3、GRUB菜单 1.4、加载 Linux 内核 1.5、init进程初始化 1.6、简述总结 1.7、初始化进程centos 6和7的区别 二、排除启动类故障 2.1、修复MBR扇区故障 2.1.1、 实验 2.2、修复grub引导故障 2.2.1、实…

Marin说PCB之total etch length规则知多少?

魔都上海最近迎来了一轮梅雨季节了&#xff0c;小编我上周就已经提前把被子衣服袜子都晒了一遍&#xff0c;省的后面一段时间下雨就不能晒了。这种阴雨绵绵的天气当然在家里睡觉最舒服了&#xff0c;上周留正当我在家里夏眠的时候&#xff0c;突然被一阵手机铃声吵醒了&#xf…

Spring Boot如何实现跨域资源共享(CORS)?

&#x1f345; 作者简介&#xff1a;哪吒&#xff0c;CSDN2021博客之星亚军&#x1f3c6;、新星计划导师✌、博客专家&#x1f4aa; &#x1f345; 哪吒多年工作总结&#xff1a;Java学习路线总结&#xff0c;搬砖工逆袭Java架构师 &#x1f345; 技术交流&#xff1a;定期更新…

ArkTS开发系列之Web组件的学习(2.9)

上篇回顾&#xff1a;ArkTS开发系列之事件&#xff08;2.8.2手势事件&#xff09; 本篇内容&#xff1a; ArkTS开发系列之Web组件的学习&#xff08;2.9&#xff09; 一、知识储备 Web组件就是用来展示网页的一个组件。具有页面加载、页面交互以及页面调试功能 1. 加载网络…

多商户万能DIY商城小程序源码系统 支持自营+独立部署 带完整的安装代码包以及搭建教程

系统概述 多商户万能 DIY 商城小程序源码系统是一个综合性的电商平台解决方案&#xff0c;旨在满足不同用户的多样化需求。它不仅支持自营模式&#xff0c;还为多商户入驻提供了广阔的空间&#xff0c;使平台能够汇聚各类商品和商家&#xff0c;形成一个丰富多样的商业生态。 …

字节发布Depth Anything V2深度模型,比 Depth Anything V1 更精细的细节。

欢迎点击关注下方公众号并加入官方读者交流群&#xff0c;一个有趣有AI的AIGC公众号:关注AI、深度学习、计算机视觉、AIGC、Stable Diffusion、Sora等相关技术&#xff0c;欢迎一起交流学习&#x1f497;&#xff5e; 字节发布Depth Anything V2深度模型。比 Depth Anything V1…

昇思25天学习打卡营第3天|onereal

前几天不能运行代码&#xff0c;经过排查是因为我的浏览器是搜狗的&#xff0c;换成Chrome问题解决了。按照提示学习了《应用实践/计算机视觉/FCN图像语义分割.ipynb》并且尝试运行代码&#xff0c;开始训练&#xff0c;最后看到图片变化。 网络流程 FCN网络的流程如下图所示&…

【课程总结】Day11(下):YOLO的入门使用

前言 YOLO的简介 YOLO&#xff08;You Only Look Once&#xff09;是一种流行的目标检测算法&#xff0c;由Joseph Redmon等人于2015年提出。YOLO的设计思想是将目标检测任务转化为单个神经网络的回归问题&#xff0c;通过在图像上划分网格并对每个网格预测边界框和类别置信度…

Node.js全栈指南:浏览器显示一个网页

上一章&#xff0c;我们了解到&#xff0c;如何通过第二章的极简 Web 的例子来演示如何查看官方文档。为什么要把查阅官方文档放在前面的章节说明呢&#xff1f;因为查看文档是一个很重要的能力&#xff0c;就跟查字典一样。 回想一下&#xff0c;我们读小学&#xff0c;初中的…

如何创建一个vue项目

目录 1.环境准备 2.检查node和npm版本&#xff0c;确定已安装nodejs 3.全局安装vue/cli、webpack、webpack-cli、vue/cli-init 4.检查vue版本,注意V是大写 5.创建vue项目 6.得到的vue项目目录结构如下&#xff1a; 1.环境准备 安装nodejs,或者安装nvm&#xff0c;并使用…

day38动态规划part01| 理论基础 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

**理论基础 ** 无论大家之前对动态规划学到什么程度&#xff0c;一定要先看 我讲的 动态规划理论基础。 如果没做过动态规划的题目&#xff0c;看我讲的理论基础&#xff0c;会有感觉 是不是简单题想复杂了&#xff1f; 其实并没有&#xff0c;我讲的理论基础内容&#xff0c;…

盲源信道分离—FastICA算法性能仿真

本案例中使用Matlab软件对FastICA算法的声音分离性能进行了仿真&#xff0c;分别对简单波形的混合信号、不同类型声音的混合信号、同一类型的混合信号这三种情况进行仿真&#xff0c;主要从分离信号的波形形状、串音误差两方面对分离性能进行衡量&#xff0c;仿真结果显示快速I…

前端新手小白的第一个AI全栈项目---AI聊天室

前言 ok&#xff0c;大家好。- ̗̀(๑ᵔ⌔ᵔ๑)最近也是想做自己的第一个前后端分离的项目&#xff0c;刚好最近学了一点AI接口的实现。想着用接口做一个自己的ai聊天室并且尝试一下全栈式开发。中间真的解决了很多问题&#xff0c;也是成功之后也是想要将实现过程分享一下&a…

4.任务调度

1.基本知识 2.任务的状态 FreeRTOS中任务共存在4种状态&#xff1a;Running 运行态 当任务处于实际运行状态称之为运行态&#xff0c;即CPU的使用权被这个任务占用&#xff08;同一时间仅一个任务处于运行态&#xff09;。Ready 就绪态 处于就绪态的任务是指那些能够运行&…

6毛钱SOT-23封装28V、400mA 开关升压转换器,LCD偏置电源和白光LED应用芯片TPS61040

SOT-23-5 封装 TPS61040 丝印PHOI 1 特性 • 1.8V 至 6V 输入电压范围 • 可调节输出电压范围高达 28V • 400mA (TPS61040) 和 250mA (TPS61041) 内部开关电流 • 高达 1MHz 的开关频率 • 28μA 典型空载静态电流 • 1A 典型关断电流 • 内部软启动 • 采用 SOT23-5、TSOT23…