3. gRPC 基础回顾:Protocol Buffers 语法、gRPC 四种通信模式及其适用场景
在开始报表导出架构重构之前,必须夯实 gRPC 的核心基础。本章将系统回顾 Protocol Buffers(protobuf) 的接口定义语法,以及 gRPC 的 四种通信模式。理解这些基础概念,是后续定义导出服务接口、规划消费组拓扑的前提。
3.1 Protocol Buffers 语法速览
gRPC 默认使用 Protocol Buffers 作为接口定义语言(IDL)和序列化协议。一个典型的 .proto 文件包含消息类型定义和服务定义。
3.1.1 消息类型定义
使用 message 关键字定义数据结构,每个字段有类型、名称和唯一的编号。
syntax = "proto3";
package reportexport;
// 定义导出请求消息
message ExportRequest {
string report_id = 1; // 报表唯一标识
string format = 2; // 导出格式:PDF, CSV, XLSX
int32 page_size = 3; // 分页大小(可选)
bool include_charts = 4; // 是否包含图表
map<string, string> filters = 5; // 过滤条件
}
// 定义导出响应消息
message ExportResponse {
string job_id = 1; // 异步任务ID
string status = 2; // 任务状态:PENDING, RUNNING, COMPLETED, FAILED
string download_url = 3; // 下载链接(完成后提供)
}
3.1.2 服务定义
使用 service 关键字定义 RPC 方法,指定输入和输出消息类型。
service ReportExportService {
// 一元 RPC:同步导出
rpc ExportReport (ExportRequest) returns (ExportResponse);
// 服务端流式 RPC:实时推送导出进度
rpc ExportReportProgress (ExportRequest) returns (stream ProgressMessage);
// 客户端流式 RPC:分批上传数据后导出
rpc ExportFromStream (stream DataChunk) returns (ExportResponse);
// 双向流式 RPC:实时交互式导出
rpc InteractiveExport (stream ExportCommand) returns (stream ExportEvent);
}
字段编号规则: 1-15 编号使用 1 字节编码,适合频繁出现的字段;16-2047 编号使用 2 字节编码。预留 19000-19999 作为 protobuf 内部保留编号。
3.2 gRPC 四种通信模式
gRPC 基于 HTTP/2 提供了四种通信模式,分别适用于不同的业务场景。下表总结了它们的核心差异:
| 通信模式 | 请求方式 | 响应方式 | 典型场景 |
|---|---|---|---|
| Unary(一元) | 单次请求 | 单次响应 | 传统 RPC、查询、简单操作 |
| Server Streaming(服务端流) | 单次请求 | 多次响应(流) | 进度推送、日志流、大文件分块 |
| Client Streaming(客户端流) | 多次请求(流) | 单次响应 | 批量上传、数据采集、长事务提交 |
| Bidirectional Streaming(双向流) | 多次请求(流) | 多次响应(流) | 实时交互、聊天、协同编辑 |
3.3 四种模式详解与适用场景
3.3.1 Unary(一元 RPC)
客户端发送一个请求,服务端返回一个响应。这是最基础的 RPC 模式,行为与传统的 HTTP REST 类似。
- 适用场景: 报表元数据查询、配置获取、简单的同步导出(小文件)。
- 优点: 实现简单,调试方便,延迟可控。
- 缺点: 不适合大数据量传输或长时间处理,客户端需等待完整响应。
3.3.2 Server Streaming(服务端流式 RPC)
客户端发送一个请求,服务端返回一个消息流。服务端可以持续推送数据,直到流结束。
- 适用场景: 报表导出进度实时推送、大文件分块下载、实时日志流。
- 优点: 客户端无需轮询,减少网络开销;支持实时反馈。
- 缺点: 客户端需处理流式数据,连接可能因网络中断。
3.3.3 Client Streaming(客户端流式 RPC)
客户端发送一个消息流,服务端接收完所有消息后返回一个响应。
- 适用场景: 批量上传报表数据、分段提交大型查询参数、IoT 设备数据采集。
- 优点: 支持大数据量分片上传,降低单次请求负载。
- 缺点: 服务端需等待所有数据到达后才能处理,延迟较高。
3.3.4 Bidirectional Streaming(双向流式 RPC)
客户端和服务端可以同时发送和接收消息流,两者独立且异步。
- 适用场景: 实时交互式报表编辑、协同过滤、在线游戏状态同步。
- 优点: 低延迟、全双工通信,适合需要频繁双向交互的场景。
- 缺点: 实现复杂度高,需处理流状态管理和背压(backpressure)。
架构决策提示: 在报表导出架构中,服务端流式 RPC 是核心模式,用于实时推送导出进度和分块传输结果文件。双向流式 RPC 可用于高级交互式导出场景,但会增加消费组管理的复杂度,建议仅在明确需求时引入。
3.4 四种通信模式对比图
下图直观展示了四种模式的请求-响应交互流程:
3.5 在报表导出架构中的映射
结合本课程的业务场景,四种模式在报表导出架构中的具体映射如下:
| 通信模式 | 报表导出场景 | 接口示例 |
|---|---|---|
| Unary | 查询导出任务状态、获取报表元数据 | GetExportStatus(StatusRequest) returns (StatusResponse) |
| Server Streaming | 实时推送导出进度、分块传输导出文件 | ExportReportProgress(ExportRequest) returns (stream ProgressMessage) |
| Client Streaming | 分批上传报表模板或数据源 | UploadTemplate(stream TemplateChunk) returns (UploadResponse) |
| Bidirectional Streaming | 交互式报表参数调整与预览 | InteractiveExport(stream ExportCommand) returns (stream ExportEvent) |
关键结论: 在后续的消费组规划中,服务端流式 RPC 将作为导出任务的核心通信模式,用于实现进度推送和结果分块传输。一元 RPC 用于管理面操作(查询状态、取消任务)。客户端流式 和 双向流式 作为高级特性,仅在特定需求下引入。