avatar

Ycyofmine’s Blog

云鸮雨霁

  • 首页
  • 分类
  • 标签
  • 归档
  • 关于
首页 RPC:原理、组成与局限性
文章

RPC:原理、组成与局限性

发表于 2025/05/08
作者 Ycyofmine
12 分钟阅读

1.什么是RPC

RPC 全称 Remote Procedure Call ——远程过程调用。在分布式系统高速发展的今天,大量服务被部署在不同服务器上,服务器之间的系统、CPU指令集、大小端策略各有不同,如何高效、无感地调用服务就是RPC的目标。

2.RPC核心组成

RPC核心组成如下:

  • client(服务调用者)
  • stub(本地存根,也分为调用端和服务端的本地存根)
  • server(服务提供者)
  • RPCRuntime(RPC通信者)

服务调用者、调用端的本地存根及其中一个RPC通信包的实例存在于调用端的机器上,而服务提供者、服务提供端的存根及另一个RPC通信包的实例存在于被调用的机器上。

2.1 Client (服务调用者)

Client,是分布式系统中发起远程过程调用的应用程序或进程。它希望执行位于远程服务器上的某个特定功能或服务,但本身并不包含实现该功能的代码。Client 的主要职责是初始化调用请求,包括指定目标服务、方法以及传递必要的参数。它通过本地存根(Client Stub)来与远程服务进行交互,使得远程调用看起来像本地调用一样简单。

接下来,笔者会用点外卖为例子形象地描述RPC调用过程。

在点外卖的场景中,你就是 Client。你想吃饭(调用服务),但你不想或不能自己做(本地执行)。于是,你决定从餐馆(Server)点一份外卖。你明确知道你想吃什么(调用哪个方法,比如“宫保鸡丁”),可能还有一些特殊要求(传递参数,比如“微辣”、“不要香菜”)。

2.2 Server (服务提供者)

Server,是分布式系统中实际拥有并执行特定功能或服务的应用程序或进程。一旦接收到请求,Server 会通过其本地存根(Server Stub)解析请求,找到对应的本地方法并执行,然后将执行结果返回给调用方。

在这个场景中,餐馆 就是 Server。餐馆拥有厨房、厨师和食材(实际的服务资源和执行能力),能够制作你点的菜品(执行具体的方法,比如烹饪“宫保鸡丁”)。

2.3 Stub (本地存根)

本地存根的存在就是为了让远程调用本地调用一样直接进行函数调用,无需关心地址空间隔离、函数不匹配等问题。本地存根的职责就是进行类型和参数化。也就是说本地存根隐藏了远程调用的实现细节,可以让Client感觉调用远程方法就像是调用本地方法一样。

  1. 你手机上的外卖 App (客户端存根): 在你点外卖时,手机上的外卖 App 就扮演了客户端存根的角色。它将你选择的菜品(比如“宫保鸡丁,微辣”)和地址等信息,打包成一个标准化的电子订单,然后通过互联网发送给餐馆的系统。之后,当餐馆确认订单、骑手取餐或外卖送达时,App 会接收这些从远端传来的状态更新,并清晰地展示给你。
  2. 餐馆的接单系统/前台 (服务端存根): 餐馆里用来接收和处理外卖订单的系统则扮演了服务端存根的角色。它通过互联网接收到你的 App 发来的电子订单,然后解析这个订单,搞清楚具体要做什么菜、有什么特殊要求,并把这些信息准确传达给后厨(真正的服务执行者)。当菜品制作完成或订单状态有任何变动时,这个系统会把这些信息(比如“已出餐”,“准备配送”)打包成标准格式,再通过互联网发送回你的外卖 App。

2.4 RPCRuntime (RPC通信者)

RPCRuntime负责处理 Client 和 Server 之间实际的网络通信细节。它为上层的 Stub 提供了透明的通信服务,使得 Stub 无需关心底层复杂的网络协议、数据传输、连接管理、错误处理等问题。在服务调用端和服务提供端都有一个RPCRuntime实例,负责双方之间的通信,可靠地将存根传递的数据包传输到另一端。市面上的主流RPC框架,如Google的grpc、Facebook的Thrift和腾讯的TARS,大都采用TCP(有的框架支持多种,如UDP或HTTP)

在点外卖的场景中, RCPRuntime 负责所有数据(订单、状态)的实际“跑腿”工作和“交通规则”,以及最终“实物”的运送,让你和餐馆的“存根”可以专注于下单和做菜,而不用操心信息是怎么传的、菜是怎么送的。

3. HTTP与RPC

不少人会疑惑,为什么有HTTP了还要用RPC?

  • 首先,HTTP与RPC都属于网络四层模型中的应用层,它们都只是定义了不同消息格式的应用层协议而已。

  • HTTP 协议由于其通用性、可读性(如JSON)以及广泛的浏览器和工具支持,更多用于面向最终用户(ToC)的应用,如网页浏览、公开的REST API等。RPC则更常用于企业内部服务之间(ToB或Backend),追求内部系统间调用的效率和便捷性,通常对开发者屏蔽底层网络细节。

  • 虽然两者都可以集成服务发现(如Consul, ZooKeeper),但RPC框架通常与服务发现结合更紧密,因为其调用方式更像函数调用(需明确知道服务名和方法名)。HTTP API的服务发现可能更多依赖DNS、负载均衡器或API网关进行路由。

  • 两者主要都使用TCP作为底层传输协议。但传统HTTP/1.1在连接复用和队头阻塞方面存在效率问题(除非精细使用Keep-Alive)。RPC框架(尤其是基于自定义TCP协议或像gRPC那样使用HTTP/2的)通常更注重连接的复用和传输效率,致力于减少网络开销。

  • HTTP/1.1的头部信息是文本格式,相对冗长,对于频繁的小请求,头部开销占比可能较大。许多RPC协议(如Thrift、Protocol Buffers)采用二进制格式进行数据序列化和传输,数据包更紧凑。现代RPC如gRPC,通过HTTP/2的头部压缩(HPACK)也显著减少了这部分开销。

4. RPC的局限性

4.1 高度依赖网络质量:

RPC的性能和可靠性直接受制于底层网络的稳定性与延迟。网络发生抖动、出现高延迟或连接中断时,RPC调用的成功率和响应速度会受到显著影响。

4.2 难以调试与定位问题:

由于RPC调用跨越了单一进程或单台计算机的边界,其调试和故障排查通常比本地调用更为困难。定位一个问题可能需要追踪分布在多个服务节点间的调用链路,往往需要借助分布式日志系统、链路追踪等专门工具。

4.3 数据传输的限制:

部分RPC框架可能对传输数据包的大小或支持的数据类型有所限制。当需要传输大量数据或非常复杂的数据结构时,可能会因序列化/反序列化开销增大、超出框架缓冲区限制或网络拥塞等因素导致性能瓶颈。

4.4 调用失败

调用失败通常由多种因素引起,包括服务端异常、传输结果丢失等。尽管多数 RPC 框架提供了超时控制、重试机制等可靠性增强功能,但在复杂的分布式环境中,网络分区、服务过载或节点故障等问题仍可能导致 RPC 调用失败或消息丢失。如果网络传输协议自带重传机制,可以部分解决这些问题;但如果使用的协议不支持重传,程序员就需要手动实现重传逻辑以确保数据的可靠传输。

网络
计网
本文由作者按照 CC BY 4.0 进行授权
分享

最近更新

  • ROS2中并发连接蓝牙手柄排错过程
  • 自行编译ros2-humble-plotjuggler
  • Ubuntu 22.04上蓝牙无法打开——(MT7922网卡为例)
  • Isaac sim遥操作控制
  • RPC:原理、组成与局限性
外部链接
  • codetime
  •  此博客的 Github 仓库

文章内容

相关文章

2024/11/14

OSI与TCP/IP分层模型及各层协议介绍

分层模型 OSI 共七层,属于学院派。 物理层 链路层 网络层 传输层 会话层 表达层 应用层 TCP/IP 属于实践派。 共五层,属于实践派。 物理层 链路层 网络层 传输层 应用层 与OSI相比,OSI的会话层、表达层被囊括进应用层了。 层的具体含义 物理层 设备与设备之间用来链接的网线 ...

Isaac通过ros2控制机器人

Isaac sim遥操作控制

© 2025 Ycyofmine. 保留部分权利。

本站采用 Jekyll 主题 Chirpy

热门标签

games104 UE c++ robot OS 装机 计网 essay

发现新版本的内容。