4. gRPC 通信模式概览:Unary、Server Streaming、Client Streaming、Bidirectional Streaming
gRPC 基于 HTTP/2 协议,定义了四种核心的远程过程调用(RPC)通信模式。理解这四种模式是设计微服务间数据流架构的基础。它们从最简单的请求-响应,逐步演进到全双工的双向流式通信,为不同业务场景提供了精准的传输语义。
4.1 四种通信模式总览
下表从调用方视角、数据流方向、典型应用场景三个维度,对四种模式进行了对比:
| 模式名称 | 调用方视角 | 数据流方向 | 典型应用场景 |
|---|---|---|---|
| Unary RPC | 客户端发送 1 个请求,服务端返回 1 个响应 | 客户端 → 服务端 → 客户端 | 传统 CRUD 操作、用户登录、配置查询 |
| Server Streaming RPC | 客户端发送 1 个请求,服务端返回多个响应 | 客户端 → 服务端 →→→ 客户端 | 日志推送、实时监控指标、大文件分块下载 |
| Client Streaming RPC | 客户端发送多个请求,服务端返回 1 个响应 | 客户端 →→→ 服务端 → 客户端 | 批量数据上传、传感器数据聚合、长时任务提交 |
| Bidirectional Streaming RPC | 客户端和服务端各自独立发送多个消息 | 客户端 ↔ 服务端(全双工) | 实时聊天、游戏状态同步、AI 对话流式推理 |
4.2 Unary RPC(一元模式)
Unary 是最基础的 RPC 模式,与传统的 HTTP REST 调用在语义上最为接近。客户端发起一个请求后阻塞等待,服务端处理完成后返回一个响应。在微服务架构中,Unary 适用于查询服务状态、获取单个实体详情等低延迟、高一致性的场景。
性能提示: 在 gRPC 中,Unary 调用虽然简单,但依然受益于 HTTP/2 的多路复用和头部压缩。与 REST 相比,Unary 的序列化开销更低,延迟通常可降低 30%-50%。
4.3 Server Streaming RPC(服务端流模式)
当服务端需要向客户端推送大量数据或持续事件时,Server Streaming 模式是首选。客户端发送一个请求后,通过一个 Stream 对象持续读取服务端返回的消息,直到服务端关闭流。
在微服务架构中,该模式常用于:
- 日志中心:客户端订阅某个服务实例的日志,服务端持续推送日志行。
- 监控告警:客户端请求订阅某个指标,服务端按时间窗口推送聚合后的数据点。
- 数据导出:客户端请求导出大量数据,服务端分页或分块流式返回。
4.4 Client Streaming RPC(客户端流模式)
Client Streaming 模式允许客户端发送多条消息,服务端在接收完所有消息后,返回一个最终的聚合响应。这种模式非常适合需要客户端批量提交数据的场景。
典型应用包括:
- 批量订单处理:客户端逐条发送订单,服务端在流关闭后返回处理结果汇总。
- 文件上传:客户端将大文件分片发送,服务端在接收完成后返回文件存储路径。
- IoT 数据采集:传感器设备持续上报数据点,服务端在收集完一个时间窗口的数据后,返回统计摘要。
4.5 Bidirectional Streaming RPC(双向流模式)
双向流模式是 gRPC 最强大的通信模式。客户端和服务端可以独立、并发地发送和接收消息,形成全双工的数据通道。消息的顺序在单个流内是保序的,但客户端和服务端的读写操作是完全异步的。
架构要点: 双向流并不要求客户端和服务端的消息一一对应。服务端可以在收到客户端第 1 条消息后立即回复多条,也可以在收到第 10 条消息后再统一回复。这种灵活性使得双向流非常适合实现“请求-响应”的异步变体。
在微服务架构中的典型场景:
- 实时协同编辑:多个客户端通过网关与文档服务建立双向流,同步光标位置和编辑操作。
- AI 对话服务:客户端流式发送用户输入,服务端流式返回模型推理的 token,实现类 ChatGPT 的交互体验。
- 服务网格控制面:控制面与数据面代理建立双向流,动态下发路由规则并接收代理的健康状态。
4.6 四种模式的流式架构对比
下面的 SVG 图展示了四种通信模式在微服务调用中的数据流形态,帮助理解不同模式下的连接生命周期和消息传递方向。
4.7 流式通信的微服务架构映射
在微服务架构中,选择合适的 gRPC 通信模式直接影响系统的吞吐量、延迟和资源利用率。下面的架构图展示了四种模式在典型微服务拓扑中的部署位置:
4.8 选择通信模式的决策流程
在实际微服务设计过程中,可以按照以下步骤快速确定使用哪种 gRPC 模式:
- 判断数据量:如果请求和响应数据量都很小(< 1MB),优先考虑 Unary。
- 判断数据方向:如果只有服务端需要推送大量数据,选择 Server Streaming;如果只有客户端需要批量发送,选择 Client Streaming。
- 判断交互实时性:如果双方需要持续、异步地交换消息,选择 Bidirectional Streaming。
- 评估连接复用:在长连接场景下,流式模式(尤其是双向流)可以显著减少连接建立和 TLS 握手的开销。
避坑指南: 不要将 Bidirectional Streaming 当作“双向 Unary”使用。如果客户端和服务端的消息是一一对应的,使用 Unary 配合异步回调或 Future 模式会更简单、更易于调试。双向流更适合消息频率和数量都不对称的场景。