Skip to main content

gRPC 四种 RPC 通信模式

这四种流式通信模式,本质上是由 客户端发起的请求流服务端返回的响应流 组合而成的。核心区别在于发送或接收消息的次数

我用一张表帮你快速理清,再逐一深入讲解:

模式客户端请求服务端响应适用场景
1. 一元 RPC (Unary)1 条1 条普通接口调用,如同步函数
2. 服务端流式 (Server Streaming)1 条N 条(流)服务端持续推送数据
3. 客户端流式 (Client Streaming)N 条(流)1 条客户端批量上传或持续上报
4. 双向流式 (Bidirectional Streaming)N 条(流)N 条(流)实时全双工交互

1. 一元 RPC (Unary RPC)

这是最“经典”的 RPC 模式,和普通的 HTTP 请求/响应完全一致。

  • 行为:客户端发送一个请求,阻塞等待,直到服务端返回一个响应。
  • proto 定义:不加 stream 关键字。
    rpc GetUser (UserIdRequest) returns (UserResponse);
  • 典型场景:登录验证、获取用户详情、订单查询等常规读写操作。

2. 服务端流式 RPC (Server Streaming RPC)

客户端发送一个请求,服务端会返回一个数据流(可以持续发送多条消息)。

  • 行为:客户端发起请求后,会持续监听(非阻塞),服务端可以多次调用 Send() 方法发送数据,直到发送完毕并告知客户端结束。
  • proto 定义:在 returns 前加 stream
    rpc GetStockPrice (StockRequest) returns (stream StockPrice);
  • 典型场景
    • 实时行情:客户端请求某只股票,服务端持续推送最新股价。
    • 大日志导出:客户端请求导出一个月的大文件日志,服务端分块流式返回,避免内存溢出。
    • 进度推送:客户端发起长耗时任务(如视频转码),服务端通过流实时返回当前进度百分比。

3. 客户端流式 RPC (Client Streaming RPC)

客户端发送一个数据流到服务端,服务端处理完所有数据后,只返回一个最终响应。

  • 行为:客户端可以多次调用 Send() 发送数据,发送完成后调用 CloseAndRecv() 告知服务端“我发完了”。服务端接收完所有数据,处理完毕后返回一个响应。
  • proto 定义:在 request 前加 stream
    rpc UploadFile (stream FileChunk) returns (UploadStatus);
  • 典型场景
    • 大文件上传:客户端将大文件切成多个数据块(Chunk)分片上传。
    • 物联网数据上报:传感器设备不断向服务器上报温度、湿度数据,服务器汇总计算后返回一个平均指标。

4. 双向流式 RPC (Bidirectional Streaming RPC)

这是最强大的模式。客户端和服务端各自独立地维持一个读写数据流,双方可以同时发送和接收消息。

  • 行为:调用开始后,双方维持长连接。客户端和服务端的发送和接收完全解耦且异步(顺序由业务逻辑决定,但消息顺序在各流内是保序的)。
  • proto 定义:在 requestreturns 前都加 stream
    rpc Chat (stream ChatMessage) returns (stream ChatMessage);
  • 典型场景
    • 实时聊天室:用户发送消息的同时,实时接收其他人发送的消息。
    • 实时游戏同步:客户端发送玩家操作指令,服务端推送其他玩家的位置状态。
    • 分布式协同:两个微服务之间建立长连接,实时交换监控状态或配置变更通知。

⚠️ 实现原理上的一点重要补充

理解双向流时,要记住一个底层特性:双向流并不是一条“双绞线”,而是两条独立的“单向流水线”(基于 HTTP/2 的多路复用)。这意味着:

  1. 服务端可以等到接收完所有客户端消息再开始发送响应,也可以在刚收到第一条请求时就开始发送响应,完全不依赖于客户端的发送进度。
  2. 每条流内的消息顺序有保证(先发的先到),但客户端流和服务端流之间的消息顺序无法相互保证。

如何选择?

  • 服务间同步调用:直接用 一元 RPC,简单高效。
  • 数据量过大:用 服务端流(拉取大数据)或 客户端流(上传大数据)。
  • 需要实时推送:用 服务端流(如推送新闻)或 双向流(如即时通讯)。
  • 两端都需要随时发送数据:请毫不犹豫选择 双向流式