什么是 RPC?

RPC 是指远程过程调用,也就是说两台服务器 A,B 一个应用部署在 A 服务器上,想要调用 B 服务器上应用提供的函数或方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。

RPC 是如何通讯的?

  1. 要解决通讯的问题,主要是通过在客户端和服务器之间建立 TCP 连接,远程过程调用的所有交换的数据都在这个连接里传输。连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远程过程调用共享同一个连接。
  2. 要解决寻址的问题,也就是说,A 服务器上的应用怎么告诉底层的 RPC 框架,如何连接到 B 服务器(如主机或 IP 地址)以及特定的端口,方法的名称是什么,这样才能完成调用。比如基于 Web 服务协议栈的 RPC,就要提供一个 endpoint URI,或者是从 UDDI 服务上查找。如果是 RMI 调用的话,还需要一个 RMI Registry 来注册服务的地址。
  3. 当 A 服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如 TCP 传递到 B 服务器,由于网络协议是基于二进制的,内存中的参数的值要序列化成二进制的形式,也就是序列化(Serialize)或编组(marshal),通过寻址和传输将序列化的二进制发送给 B 服务器。
  4. B 服务器收到请求后,需要对参数进行反序列化(序列化的逆操作),恢复为内存中的表达方式,然后找到对应的方法(寻址的一部分)进行本地调用,然后得到返回值。
  5. 返回值还要发送回服务器 A 上的应用,也要经过序列化的方式发送,服务器 A 接到后,再反序列化,恢复为内存中的表达方式,交给 A 服务器上的应用。

为什么要用 RPC?

就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如比如不同的系统间的通讯,甚至不同的组织间的通讯。由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用。

通讯五步与动机都已讲清,但”理解 RPC 框架”还要再上两层:框架在五步之上额外解决了什么(治理面),以及RPC 与 HTTP API 的架构位差。本文补全这两层,形成完整理解。

五步之上的框架职责:治理面

裸 Socket 能跑通五步,但生产 RPC 框架 80% 的代码在治理面:

  • 服务发现:注册中心(ZK/Nacos)维护”接口→实例列表”,客户端订阅变更——解决”寻址”的动态版(实例上下线、扩缩容)
  • 负载均衡:客户端侧策略(轮询/加权/一致性哈希/P2C),配合健康检查剔除坏实例
  • 容错:失败重试(幂等前提)、failover 换实例、failfast 快速失败、熔断降级(连续失败开路)
  • 超时与预算:调用超时、重试预算、deadline 传播(防止重试风暴放大故障)
  • 可观测:每次调用生成 trace span、指标(QPS/延迟/错误率)、访问日志
  • 安全:mTLS/令牌鉴权、服务间授权

一句话:**五步让调用”能通”,治理面让调用”可靠、可控、可观测”**。评价一个 RPC 框架的成熟度,看治理面而非协议本身。

协议设计的权衡

维度 二进制 RPC(Dubbo/gRPC) HTTP/JSON(REST)
性能 长连接+紧凑编码,高吞吐低延迟 文本冗余、短连接开销(HTTP2 缓解)
契约 IDL/接口强约束,编译期检查 文档约束,运行期才发现不一致
调试 需工具解码 curl 即调
跨语言 IDL 生成多语言 stub 天然跨语言
生态 内网服务间 对外开放、浏览器可达

选型经验:内网服务间高频调用走 RPC,边界对外开放走 HTTP API;gRPC 用 Protobuf+HTTP2 在两者间取了平衡(强契约+跨语言+多路复用)。

与本地调用的语义差(理解 RPC 的哲学核心)

RPC 的目标是”像本地调用”,但分布式八谬误提醒差异不可消除:

  • 本地调用要么成功要么抛异常;RPC 还有”结果未知的超时“——可能服务端已执行成功,重试即重复执行 → 幂等性是 RPC 接口的设计义务
  • 本地调用毫秒内完成且参数引用传递;RPC 有序列化成本与深拷贝语义 → 大对象参数要警惕
  • 本地调用无部分失败;RPC 链路任一环节可失败 → 调用方必须有降级预案

优秀的 RPC 使用方式不是假装网络不存在,而是让框架隐藏通讯细节、让开发者正视失败语义——接口设计幂等、超时显式、降级内置。

一次 Dubbo/gRPC 调用的对象旅程(串联全部概念)

代理对象拦截 → 请求对象(接口/方法/参数/attachments)→ 序列化(Hessian/Protobuf)→ 长连接发送(带 requestId)→ 服务端反序列化 → 反射/生成代码分发到实现 → 执行 → 响应序列化回传 → 客户端按 requestId 唤醒 Future → 返回/抛远程异常。治理面(发现/负载/熔断/追踪)包裹在这条旅程的每一步之外。

理解 RPC 框架 = 理解三层:通讯五步(能通)→ 治理面(可靠可控可观测)→ 分布式语义差(幂等/超时/降级)。三层都答到,”怎么理解 RPC”才是完整答案。