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)机制,定义了四种通信模式,覆盖从简单请求到复杂双向流的全部场景。下图展示了四种模式的核心流程:

gRPC 四种通信模式 ① Unary RPC(一元 RPC) 客户端发送单个请求,服务端返回单个响应。 最基础的 RPC 模式,类似传统函数调用。 Client Server 请求 响应 ② Server Streaming RPC(服务端流) 客户端发送单个请求,服务端返回多个响应。 适用于订阅、日志推送、批量查询等场景。 Client Server 请求 响应流 ③ Client Streaming RPC(客户端流) 客户端发送多个请求,服务端返回单个响应。 适用于文件上传、批量数据提交等场景。 Client Server 请求流 响应 ④ Bidirectional Streaming RPC(双向流) 客户端和服务端可同时发送多个请求/响应。 适用于实时聊天、游戏同步、实时数据管道。 Client Server 请求流 响应流

四种模式在压测中的关注点各有不同:

通信模式 压测核心指标 典型压测场景
Unary RPC QPS、延迟 P99、错误率 标准 API 接口压测,如用户登录、订单查询
Server Streaming 消息吞吐量、流完成时间、背压表现 日志推送、实时监控数据流
Client Streaming 上传速率、批量提交成功率、内存占用 文件上传、批量数据导入
Bidirectional Streaming 双向消息延迟、并发流数、流控效果 实时聊天、协同编辑、游戏状态同步
压测实战要点: 双向流压测时,客户端和服务端可能因流控(Flow Control)导致相互等待,压测脚本需模拟真实的读写交替节奏,避免因单方向消息堆积造成死锁。

理解这四种通信模式,是后续设计压测场景、选择压测工具(如 ghz、k6、自定义 Go 压测客户端)以及分析压测结果的前提。在接下来的章节中,我们将基于这些模式构建完整的压测闭环。