Lazy loaded image
一次RPC调用是什么样的?
字数 829阅读时长≈ 3 分钟
2026-10-4
type
Post
status
Published
date
Oct 4, 2026
slug
rpc
summary
tags
技术探索
category
icon
password
先了解下RPC:
RPC 本质是把本地方法调用转换成远程网络调用,优点是相对于HTTP请求调用简单、性能高、适合微服务通信。
回到正题,以电商系统、订单服务调用库存服务扣减库存为例:
用户下单后,订单服务调用库存服务的 reduceStock(productId, count) 方法。其实本地是没具体实现这个方法的,订单服务调用 reduceStock() 后,RPC 框架生成的代理对象拦截这个调用。随后 RPC 框架从注册中心(如 Nacos/Zookeeper)查询库存服务实例列表。根据负载均衡策略选择一个库存服务实例。RPC 框架封装调用信息、参数序列化、协议编码。通过网络发送给库存服务。服务端收到请求后进行反序列化。根据方法名找到对应的业务实现,通过线程池执行扣库存逻辑。

具体底层是怎么实现的?

以 Dubbo RPC 为例:
  1. 客户端调用代理对象
      • 业务代码调用 inventoryService.reduceStock(productId, count)。
      • RPC 框架生成的代理对象拦截这个调用。
  1. 封装调用信息
      • RPC 框架把:
        • 接口名/方法名
        • 参数类型
        • 参数值
        • 版本信息、超时时间等元数据封装成一个 RPC 请求对象。
  1. 参数序列化
      • 将方法参数(比如 productId=1001, count=2)按照协议转换成字节流。
      • 常见序列化方式:
        • Hessian2
        • Protobuf
        • JSON 等
  1. 协议编码
      • RPC 协议会进一步把请求包装成网络传输格式。
      • 例如 Dubbo 协议会添加:
        • 请求头(调用的服务、调用的方法、请求 ID、序列化方式等)
        • 请求体(方法和参数数据)
  1. 网络发送
      • 最终形成二进制字节流,通过 TCP/HTTP2 等网络协议发送到库存服务。
  1. 服务端处理
      • 服务端收到字节流后:
        • 协议解码
        • 参数反序列化
        • 根据方法名找到对应实现
        • 执行业务逻辑
  1. 返回结果
      • 将返回值序列化 → 编码 → 网络传输 → 客户端反序列化。

为什么要封装调用信息、参数序列化、协议编码?

封装调用信息解决“让对方知道你调用什么方法”的问题,
序列化解决“数据怎么跨进程传输”的问题,
协议编码解决“双方如何按照统一格式通信”的问题。

题外话:为什么有这些优点?

RPC 的优点

  1. 调用简单
    1. 屏蔽网络通信细节,开发者像调用本地接口一样调用远程服务。
  1. 性能较高
    1. 通常使用二进制序列化和长连接,比传统 HTTP JSON 调用开销更低,适合内部服务高频调用。
  1. 接口约束明确
    1. 通常基于接口定义(IDL/接口类),参数和返回值更加规范,方便服务治理。
  1. 方便微服务拆分
    1. 服务之间通过 RPC 通信,可以独立部署、扩展。
回到首页