一文读懂 RPC:定义、调用逻辑与核心价值

198 阅读7分钟

在分布式系统中,应用部署在不同机器上,无法直接共享内存,跨机器、跨系统的通信需求催生了 RPC 技术。本文将从 RPC 的本质出发,拆解其调用过程、核心组件与框架特性,帮你理清 RPC 的核心逻辑。

一、RPC 是什么?为什么需要远程调用?

1.1 先搞懂:RPC 的定义

RPC(Remote Procedure Call,远程过程调用协议)的核心是 “让程序像调用本地函数一样,调用另一个地址空间(如远程机器)的过程或函数”—— 无需开发者手动编写网络通信代码,不用关注底层协议细节,只需聚焦业务逻辑实现。

简单说,RPC 帮开发者 “屏蔽了网络处理的复杂度”,降低了分布式编程的门槛,同时减少了网络编码的成本和出错概率。

1.2 再理解:为什么需要远程调用?

远程调用的需求源于分布式系统的本质特性,主要场景包括:

  • 跨机器 / 跨系统通信:应用部署在不同机器(如集群横向扩展),或不同组织的系统间需协作(如支付系统调用用户系统),无法通过本地调用完成;
  • 解耦与资源复用:将核心能力封装为服务(如订单服务、用户服务),供其他系统远程调用,避免重复开发,提升资源利用率;
  • 性能与稳定性需求:分布式场景下,需通过远程调用协调多机器资源,同时应对网络不稳定、机器故障等问题,而 RPC 框架能提供对应的保障机制。

二、RPC 要解决的核心问题

要实现稳定的远程调用,需突破一系列技术难点,这也是 RPC 设计的核心目标:

  1. 底层通信稳定:服务间通信需基于可靠的传输协议,通常选择 TCP(相比 UDP 更能保证数据不丢失、按序到达);
  1. 高 IO 性能:服务处理远程请求时,IO 操作(如网络读写、数据解析)需高效,避免成为性能瓶颈;
  1. 数据序列化 / 反序列化:跨机器传输的数据需转为二进制流(序列化),接收方再还原为可读格式(反序列化),需约定统一的 “数据契约”(如协议格式、数据结构);
  1. 服务地址发现:客户端需知道 “调用哪个机器的服务”,即找到可用的服务端地址;
  1. 调用逻辑映射:客户端发送的 “调用请求”(如调用哪个方法、传入什么参数),服务端需能正确解析并映射到本地函数,这需要双方约定统一的 “调用契约”。

而 RPC 的核心价值正在于:通过 “代理对象” 封装上述所有细节,让开发者无需关心技术实现,只需像调用本地函数一样发起远程请求。

三、RPC 的核心组件与调用过程

3.1 四大核心组件

RPC 架构依赖 4 个关键组件协同工作,确保调用链路通顺:

image.png

组件角色与功能
客户端(Client)服务调用方(消费者),发起远程调用请求
客户端存根(Client Stub)1. 存储服务端地址信息;2. 将客户端的调用参数(方法名、入参)序列化,打包成网络消息;3. 通过网络将消息发送给服务端
服务端存根(Server Stub)1. 接收客户端的网络消息;2. 反序列化消息,解析出调用方法和参数;3. 调用服务端本地函数处理请求
服务端(Server)服务的真正提供者,执行本地业务逻辑并返回结果

3.2 完整调用流程(9 步走)

从客户端发起请求到接收结果,RPC 的调用链路可拆解为 9 个关键步骤,清晰展现组件间的协作:

image.png

  1. 客户端发起本地调用:Client 像调用本地函数一样,调用目标服务的方法;
  1. 客户端存根封装请求:Client Stub 拦截请求,将 “方法名、入参” 等信息通过序列化(如转为二进制流)组装成网络消息;
  1. 客户端存根发送消息:Client Stub 根据存储的服务端地址,通过网络(基于 TCP 等协议)将消息发送给 Server;
  1. 服务端存根接收消息:Server Stub 接收网络消息,对消息进行反序列化,解析出调用细节(要调用的方法、参数);
  1. 服务端存根调用本地服务:Server Stub 根据解析结果,调用 Server 端的本地业务函数;
  1. 服务端处理并返回结果:Server 执行本地逻辑,将处理结果返回给 Server Stub;
  1. 服务端存根封装结果:Server Stub 将返回结果序列化,打包成网络消息,通过网络发送给 Client;
  1. 客户端存根接收并解析结果:Client Stub 接收消息,反序列化后得到可读的结果数据;
  1. 客户端获取最终结果:Client Stub 将结果返回给 Client,Client 完成一次远程调用。

四、RPC 框架的额外能力

基础的 RPC 调用仅能完成 “跨机器函数调用”,而工业级 RPC 框架(如 Dubbo、gRPC)还会集成 3 个关键能力,以适配分布式生产环境:

  1. 服务注册与发现:解决 “客户端找服务端” 的问题 —— 服务端启动时将地址注册到注册中心(如 ZooKeeper、Nacos),客户端从注册中心获取可用服务地址,避免硬编码地址;
  1. 容错机制:应对分布式环境的网络不稳定、机器故障 —— 如服务端宕机时自动切换到备用节点,请求超时后重试,避免单次故障导致调用失败;
  1. 负载均衡:合理分配请求流量,避免单台机器过载 —— 根据机器负载、响应速度等策略(如轮询、随机、权重),将客户端请求分发到不同服务端节点,保证集群稳定性。

五、RPC 与 HTTP:不是对立,而是不同维度的概念

很多人会混淆 RPC 和 HTTP,其实二者并非同一层面的对比,核心区别在于 “定位与灵活性”:

  • HTTP:是 “标准的应用层协议”,定义了统一的报文格式(如请求头、响应体)和通信规则,所有系统都能识别,适合对外提供通用接口(如 Web 服务、开放 API);
  • RPC:是 “基于通信协议的服务级封装”,可自定义底层协议(如 TCP、UDP)和数据格式,灵活性更高、性能更强,还能通过加密实现隐私保护,适合内部系统间的高效通信(如微服务集群内的服务调用)。

简单说:HTTP 是 “通用的通信标准”,RPC 是 “针对内部服务的高效调用方案”——RPC 可以基于 HTTP 实现(如 gRPC 基于 HTTP/2),也可以基于自定义 TCP 协议实现(如 Dubbo)。

六、常见的 RPC 框架

工业界常用的 RPC 框架各有侧重,可根据场景选择:

  • Dubbo:阿里开源的 Java 生态 RPC 框架,支持服务注册发现、负载均衡、容错,适合微服务架构;
  • gRPC:Google 开源,基于 HTTP/2 和 Protobuf,跨语言支持好(如 Java、Go、Python),适合跨语言服务调用;
  • Thrift:Facebook 开源,支持多语言,序列化效率高,适合对性能要求高的场景;
  • Motan、rpcx:轻量级 RPC 框架,Motan 聚焦 Java 生态,rpcx 聚焦 Go 生态,部署和使用简单。

总结

RPC 的本质是 “屏蔽远程调用的技术细节,让分布式编程像本地编程一样简单”—— 从定义到调用流程,再到框架的额外能力,核心都是围绕 “降低分布式通信成本、提升稳定性和性能”。理解 RPC 的关键,不仅要记住组件和流程,更要明白它为什么能解决分布式系统的通信痛点,以及它与 HTTP 等协议的定位差异,这样才能在实际场景中正确选择和使用 RPC 技术。