写点什么

RPC 的三大问题:跨语言、跨平台通信的终极解决方案是如何炼成的?

作者:poemyang
  • 2025-08-27
    新疆
  • 本文字数:1560 字

    阅读完需:约 5 分钟

服务间通信的效率与可靠性是系统性能和稳定性的关键。远程过程调用(RPC)作为跨进程、跨机器交互的核心机制,其传输协议的设计至关重要。一个优秀的 RPC 传输协议需要应对三大挑战:1)跨语言、跨平台的数据表示与解析;2)保障网络传输的完整性、顺序性与效率;3)在服务间建立清晰统一的调用约定。

本文将从 HTTP/2 的多路复用机制、gRPC 的标准化实践、自研 RPC 协议的架构设计,以及 ProtoBuf 的高效编解码技术四个方面,深入探讨现代 RPC 体系如何实现高效可靠的通信,并分析在公网生态与内网性能之间的双重需求下,RPC 协议的发展路径。


RPC 三个挑战:任何远程调用都无法绕开的挑战

任何一个成熟的 RPC 框架,其核心使命是让开发者能够像调用本地方法一样,无感知地调用运行在另一台机器上的服务。要实现这一透明化的体验,必须解决三个无法绕开的基本挑战:数据表示 (Data Representation)、数据传递 (Data Transmission)以及方法约定 (Method Contract)。


数据表示

远程调用天然意味着跨进程,甚至跨语言的交互。客户端可能是用 Golang 编写,而服务端可能是 Java。它们内存中的对象布局、数据类型(如整数的字节序)截然不同。如何让它们能相互理解对方发送的数据?这就是数据表示要解决的核心问题:定义一种平台无关、语言无关的“通用语言”。

这个问题的解决方案是序列化(Serialization)与反序列化(Deserialization)。它负责将一端内存中的结构化数据(如对象、结构体)转换为可在网络上传输的字节流,并在另一端将其精确地还原回来。


数据传递

有了序列化后的字节流,下一个挑战是如何在两个服务的网络连接之间可靠、高效地传递它。这里的“传递数据”通常指的是应用层协议的设计,它构建在 TCP 等传输层协议之上。TCP 协议本身是面向字节流的,它能保证数据的顺序和可靠性,但它不理解“消息”的边界。如果客户端连续发送两个 RPC 请求的字节流,服务端从 TCP 缓冲区中读取时,可能会一次性读到第一个请求的全部和第二个请求的一部分(粘包),或者只读到第一个请求的一部分(拆包)。

此外,在两个服务交互的过程中,除了需要传递序列化的业务参数和返回值,还需要交换大量的元数据(Metadata),例如:用于匹配请求和响应的唯一 ID、分布式链路追踪信息(Trace ID)、超时设置、身份认证令牌、压缩算法标识、错误码和异常信息等。这些元数据也需要被整合进当前传递的上下文中。


方法约定

在本地方法调用中,编译器或解释器会根据语言规范,将一个方法签名(如 User getUser(int id))直接解析为进程内存空间中一个子过程入口的地址指针,调用过程清晰明了。但在 RPC 中,客户端和服务端是解耦的,它们甚至可能是用完全不同的语言编写的。

那么,客户端如何跨越网络,精确地告诉服务端:“我要调用的是你暴露的‘用户服务(UserService)’中的‘获取用户信息(GetUser)’方法,并且传递的参数是一个名为‘userId’的整数”?这就是方法约定要解决的问题。

这个问题的业界标准解决方案是接口描述语言(Interface Description Language, IDL)。IDL 就像一份客户端和服务端之间签订的、具有法律效力的*“技术合同”。它使用一种中立的语法,清晰地、无歧义地规定了:

1)服务(Service)的名称:例如 UserService。

2)方法(Method)的名称:例如 GetUser。

3)每个方法的参数(Parameters):包括每个参数的名称、数据类型和顺序。

4)返回值(Return Value):包括其数据类型。

开发者首先使用 IDL 来定义服务接口,然后通过 RPC 框架提供的代码生成工具,为不同的语言(如 Java、Go、Python)自动生成客户端的存根(Stub)和服务端的骨架(Skeleton)代码。开发者只需填充服务端的业务逻辑和调用客户端的存根即可,所有底层的序列化、网络通信和方法派发都由这些自动生成的代码完成,从而实现了对开发者的透明化。


未完待续


很高兴与你相遇!如果你喜欢本文内容,记得关注哦!

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

poemyang

关注

让世界知道我的存在 2018-03-05 加入

技术/人文, 互联网

评论

发布
暂无评论
RPC的三大问题:跨语言、跨平台通信的终极解决方案是如何炼成的?_网络协议_poemyang_InfoQ写作社区