2. gRPC 基础概念
在构建高性能微服务架构时,gRPC 已成为 Go 语言生态中的首选 RPC 框架。本章将系统梳理 gRPC 的核心概念,为后续的压测闭环实战奠定理论基础。
2.1 gRPC 简介
gRPC 是由 Google 开源的高性能、跨语言的远程过程调用(RPC)框架,基于 HTTP/2 协议传输,默认使用 Protocol Buffers 作为接口定义语言(IDL)和序列化工具。其核心设计目标包括:
- 高性能:基于 HTTP/2 的多路复用、头部压缩、二进制帧传输,显著降低延迟与带宽消耗。
- 跨语言:通过 Protocol Buffers 生成多种语言的客户端/服务端代码,实现异构系统无缝通信。
- 强类型:接口定义与消息结构在 .proto 文件中严格声明,编译期即可发现类型错误。
- 流式通信:原生支持四种通信模式,覆盖请求-响应、服务端推送、客户端流式上传及双向流场景。
压测视角: gRPC 的 HTTP/2 多路复用特性使得单个连接可承载数千并发请求,压测时需重点关注连接复用率与流控策略,避免因连接数不足导致吞吐量瓶颈。
2.2 Protocol Buffers 协议
Protocol Buffers(简称 Protobuf)是 gRPC 的默认序列化协议,以 .proto 文件定义数据结构与服务接口。相比 JSON/XML,Protobuf 具有以下优势:
| 特性 | Protobuf | JSON | XML |
|---|---|---|---|
| 序列化大小 | 小(二进制,无冗余字段名) | 中(文本,含字段名) | 大(文本,含标签结构) |
| 序列化/反序列化速度 | 极快(零拷贝、固定编码) | 较快(需解析字符串) | 慢(DOM/SAX 解析) |
| 类型安全 | 强类型(编译期检查) | 弱类型(运行时检查) | 弱类型(需 Schema 验证) |
| 向后兼容 | 支持(字段编号 + 可选/重复规则) | 需手动处理 | 需手动处理 |
| 可读性 | 差(二进制不可读) | 好(文本可读) | 好(文本可读) |
一个典型的 .proto 文件示例如下:
syntax = "proto3";
package order;
service OrderService {
rpc CreateOrder (CreateOrderRequest) returns (CreateOrderResponse);
}
message CreateOrderRequest {
string user_id = 1;
repeated string product_ids = 2;
double total_amount = 3;
}
message CreateOrderResponse {
string order_id = 1;
int32 status_code = 2;
string message = 3;
}
压测避坑: Protobuf 的字段编号(field number)在序列化时直接影响编码效率。编号 1-15 使用 1 字节 tag,16-2047 使用 2 字节 tag。高频字段应分配小编号,以降低消息体积,提升压测吞吐量。
2.3 gRPC 与 REST 对比
在微服务通信选型中,gRPC 与 REST 是两大主流方案。下表从压测关键维度进行对比:
| 对比维度 | gRPC | REST |
|---|---|---|
| 传输协议 | HTTP/2(二进制帧、多路复用) | HTTP/1.1 或 HTTP/2(文本/JSON) |
| 序列化格式 | Protobuf(二进制,高效紧凑) | JSON/XML(文本,冗余大) |
| 接口定义 | .proto 文件(强类型、代码生成) | OpenAPI/Swagger(文档驱动) |
| 通信模式 | 四种模式(Unary/Server Stream/Client Stream/Bidirectional Stream) | 主要 Unary(请求-响应) |
| 浏览器支持 | 需 gRPC-Web 代理 | 原生支持 |
| 压测关注点 | 连接复用、流控、Protobuf 编解码性能 | 连接数、JSON 解析、HTTP 头开销 |
压测选型建议: 内部微服务间高频、低延迟通信优先选择 gRPC;对外 API 或需要浏览器直接访问的场景,可保留 REST 或通过 gRPC-Web 桥接。
2.4 gRPC 四种通信模式概述
gRPC 基于 HTTP/2 流(Stream)机制,定义了四种通信模式,覆盖从简单请求到复杂双向流的全部场景。下图展示了四种模式的核心流程:
四种模式在压测中的关注点各有不同:
| 通信模式 | 压测核心指标 | 典型压测场景 |
|---|---|---|
| Unary RPC | QPS、延迟 P99、错误率 | 标准 API 接口压测,如用户登录、订单查询 |
| Server Streaming | 消息吞吐量、流完成时间、背压表现 | 日志推送、实时监控数据流 |
| Client Streaming | 上传速率、批量提交成功率、内存占用 | 文件上传、批量数据导入 |
| Bidirectional Streaming | 双向消息延迟、并发流数、流控效果 | 实时聊天、协同编辑、游戏状态同步 |
压测实战要点: 双向流压测时,客户端和服务端可能因流控(Flow Control)导致相互等待,压测脚本需模拟真实的读写交替节奏,避免因单方向消息堆积造成死锁。
理解这四种通信模式,是后续设计压测场景、选择压测工具(如 ghz、k6、自定义 Go 压测客户端)以及分析压测结果的前提。在接下来的章节中,我们将基于这些模式构建完整的压测闭环。