四种 RPC 通信模式详解¶
gRPC 支持四种不同的客户端与服务端交互模型。得益于 HTTP/2 原生的双向流传输能力,每种模式都在协议层得到了原生的支持。
1. 模式概览与选型¶
| 通信模式 | 请求数据量 | 响应数据量 | 关键字定义 | 典型业务场景 |
|---|---|---|---|---|
| 简单一元 (Unary) | 1 | 1 | rpc Method(Req) returns (Resp) |
登录校验、商品详情查询、常规业务操作 |
| 服务端流式 (Server Streaming) | 1 | N | rpc Method(Req) returns (stream Resp) |
股票实时行情报送、长轮询替代、日志实时推送 |
| 客户端流式 (Client Streaming) | N | 1 | rpc Method(stream Req) returns (Resp) |
大文件分块上传、IoT 传感器批量数据汇总上报 |
| 双向流式 (Bidirectional Streaming) | N | N | rpc Method(stream Req) returns (stream Resp) |
实时视频会议信令、多人在线聊天、AI 交互对话 |
2. 一元 RPC (Unary RPC)¶
一元 RPC 是最直观的模式,行为与传统的 RESTful 请求或标准本地方法调用完全一致:客户端发送单个请求,服务端返回单个应答并关闭流。
sequenceDiagram
autonumber
participant Client as 客户端
participant Server as 服务端
Client->>Server: 发送请求头部 (HEADERS: path, metadata)
Client->>Server: 发送消息载荷 (DATA: Request) [带 END_STREAM 标志]
Server-->>Client: 发送响应头部 (HEADERS: :status=200, content-type)
Server-->>Client: 发送响应载荷 (DATA: Response)
Server-->>Client: 发送状态尾部 (HEADERS: grpc-status=0) [带 END_STREAM 标志]
契约定义¶
3. 服务端流式 RPC (Server Streaming RPC)¶
客户端发送单个请求后,服务端建立流并持续推送多个响应消息,直到所有数据发送完毕后发送包含 grpc-status 的 Trailer 尾部关闭流。
sequenceDiagram
autonumber
participant Client as 客户端
participant Server as 服务端
Client->>Server: 发送请求 (HEADERS + DATA) [流客户端半关闭]
Server-->>Client: 发送响应头 (HEADERS)
loop 持续推流
Server-->>Client: 推送响应分片 1 (DATA)
Server-->>Client: 推送响应分片 2 (DATA)
Server-->>Client: 推送响应分片 N (DATA)
end
Server-->>Client: 发送终止尾部 (Trailers: grpc-status=0) [全关闭]
契约定义与应用¶
service MarketService {
// 订阅指定股票代码的实时行情流
rpc SubscribeTicker (TickerRequest) returns (stream TickerUpdate);
}
4. 客户端流式 RPC (Client Streaming RPC)¶
客户端获取流句柄后,可以按需、分批次写入多个请求消息。全部发送完毕后,通知服务端(Half-close 半关闭),服务端处理聚合逻辑并返回唯一的响应结果。
sequenceDiagram
autonumber
participant Client as 客户端
participant Server as 服务端
Client->>Server: 发送请求头 (HEADERS)
loop 持续上传分片
Client->>Server: 写入分片 1 (DATA)
Client->>Server: 写入分片 2 (DATA)
Client->>Server: 写入分片 N (DATA)
end
Client->>Server: 客户端关闭写入端 (Half-Close)
Server-->>Client: 计算完成,返回单次响应 (DATA)
Server-->>Client: 发送终止尾部 (Trailers: grpc-status=0)
契约定义与应用¶
service FileTransferService {
// 分块上传文件,最终返回文件元数据和存储路径
rpc UploadFile (stream FileChunk) returns (UploadSummary);
}
5. 双向流式 RPC (Bidirectional Streaming RPC)¶
双方完全解耦,各自独立使用读写流。客户端和服务端可以按任意顺序发送和接收消息——例如,服务端可以在收到请求后立刻回复,或者先缓冲全部请求再批量回复,亦或边收边发。
sequenceDiagram
autonumber
participant Client as 客户端
participant Server as 服务端
Client->>Server: 协商建流 (HEADERS)
par 客户端写入流
Client->>Server: 写入 Message A
Client->>Server: 写入 Message B
and 服务端写入流
Server-->>Client: 响应 Message 1
Server-->>Client: 响应 Message 2
Server-->>Client: 响应 Message 3
end
Client->>Server: 客户端关闭写入 (Half-Close)
Server-->>Client: 服务端传输完毕并发送 Trailers (全关闭)
契约定义与应用¶
生产注意事项: 1. Goroutine / 线程泄漏防护:双向流通常在客户端和服务端各有一个常驻循环用于读取。务必监听上下文取消信号(ctx.Done()),在网络中断时及时退出循环并释放资源。
2. 流量控制:若一方发送速度远快于另一方消费速度,应充分利用 HTTP/2 提供的 Window Update 窗口流控机制,避免接收端内存堆积。