1. gRPC 基础回顾
gRPC 是 Google 开源的高性能远程过程调用(RPC)框架,基于 HTTP/2 协议传输,默认使用 Protocol Buffers(protobuf)作为接口定义语言(IDL)和序列化工具。在深入限流熔断配置之前,必须牢固掌握 gRPC 的核心概念、数据契约定义方式以及四种通信模式。
1.1 gRPC 核心概念
| 概念 | 说明 | 关键要点 |
|---|---|---|
| Service Definition | 在 .proto 文件中定义 RPC 方法及其请求/响应消息结构 |
语言中立、可跨平台生成客户端/服务端桩代码 |
| Stub | 客户端桩代码,封装了网络调用细节,使远程调用像本地方法调用 | 分为阻塞式(Unary)和异步式(Streaming) |
| Channel | 客户端到服务端的连接抽象,管理 HTTP/2 连接池、负载均衡和重试 | 可配置拦截器、压缩、认证等选项 |
| Interceptor | 拦截器(中间件),在请求/响应链中插入日志、监控、限流、熔断逻辑 | 分为客户端拦截器和服务端拦截器 |
| Deadline / Timeout | 客户端设置的最大等待时间,超时后自动取消 RPC 调用 | 推荐始终设置 deadline,防止资源泄漏 |
| Metadata | 键值对形式的附加信息,类似 HTTP 头部,用于传递认证令牌、追踪 ID 等 | 不参与序列化,独立于 protobuf 消息 |
SRE 视角: Channel 和 Interceptor 是限流熔断的植入点。限流拦截器通常挂在服务端 Interceptor 链中,熔断器则常封装在客户端 Interceptor 或 Channel 的负载均衡策略中。
1.2 Protocol Buffers 简介
Protocol Buffers(protobuf)是一种语言中立、平台中立的序列化结构化数据机制,比 JSON/XML 更小、更快、更严格。gRPC 使用 protobuf 定义服务接口和消息结构。
1.2.1 消息定义示例
syntax = "proto3";
package ecommerce.v1;
// 订单消息
message Order {
string order_id = 1;
string user_id = 2;
repeated string item_ids = 3;
double total_amount = 4;
OrderStatus status = 5;
int64 created_at = 6; // Unix 时间戳
}
enum OrderStatus {
ORDER_STATUS_UNSPECIFIED = 0;
ORDER_STATUS_PENDING = 1;
ORDER_STATUS_SHIPPED = 2;
ORDER_STATUS_DELIVERED = 3;
ORDER_STATUS_CANCELLED = 4;
}
1.2.2 服务定义示例
service OrderService {
// Unary:创建订单
rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse);
// Server Streaming:获取用户的所有订单(流式返回)
rpc ListOrders(ListOrdersRequest) returns (stream Order);
// Client Streaming:批量提交订单(流式发送)
rpc BatchCreateOrders(stream CreateOrderRequest) returns (BatchCreateOrderResponse);
// Bidirectional Streaming:实时订单状态更新
rpc OrderStatusStream(stream OrderStatusRequest) returns (stream OrderStatusResponse);
}
字段编号规则: 1~15 号字段使用 1 字节编码,适合频繁出现的字段;16~2047 号字段使用 2 字节编码。预留字段编号时注意不要与已有字段冲突。
1.3 gRPC 通信模式
gRPC 基于 HTTP/2 的流式能力,支持四种通信模式。理解每种模式的流量特征,是设计限流熔断策略的前提。
1.3.1 Unary RPC(一元 RPC)
- 流程:客户端发送一个请求 → 服务端处理 → 返回一个响应。
- 特点:与传统的 HTTP REST API 最相似,请求-响应模型。
- 限流策略:按 QPS(每秒请求数)限流,熔断基于错误率或 P99 延迟。
- 典型场景:用户登录、创建订单、查询详情。
1.3.2 Server Streaming RPC(服务端流式 RPC)
- 流程:客户端发送一个请求 → 服务端返回一个消息流(多个响应消息)。
- 特点:服务端可以持续推送数据,客户端逐条读取。
- 限流策略:除 QPS 外,需限制每条流的最大消息数或总字节数,防止慢消费导致服务端内存积压。
- 典型场景:实时日志推送、股票行情订阅、大文件下载。
1.3.3 Client Streaming RPC(客户端流式 RPC)
- 流程:客户端发送一个消息流(多个请求消息) → 服务端返回一个响应。
- 特点:客户端可以批量发送数据,服务端在所有消息接收完毕后统一处理。
- 限流策略:限制客户端单次流的最大消息数或总大小,防止服务端内存溢出。
- 典型场景:批量数据上传、IoT 设备数据上报。
1.3.4 Bidirectional Streaming RPC(双向流式 RPC)
- 流程:客户端和服务端各自独立发送消息流,双方可以同时读写。
- 特点:全双工通信,消息顺序在各自流内保持,但流之间无顺序保证。
- 限流策略:需同时控制发送和接收速率;熔断需考虑流生命周期,避免频繁重建连接。
- 典型场景:实时聊天、多人协作编辑、游戏状态同步。
常见陷阱:在流式 RPC 中,如果客户端或服务端不主动读取/写入,会导致背压(backpressure)问题,进而引发连接阻塞或内存泄漏。限流熔断配置必须与流控机制(如 Flow Control)协同工作。
1.4 gRPC 与 HTTP/2 的关系
| 特性 | HTTP/2 支持 | gRPC 利用方式 |
|---|---|---|
| 多路复用 | 单一 TCP 连接承载多个流 | 一个 Channel 可并发处理多个 RPC 调用 |
| 头部压缩 | HPACK 压缩算法 | 减少 Metadata 传输开销 |
| 流优先级 | 支持流优先级和依赖 | 可用于 QoS 调度(部分实现支持) |
| Server Push | 服务端主动推送资源 | gRPC 未使用,但流式 RPC 可模拟类似效果 |
| 双向流 | 全双工流 | Bidirectional Streaming 的基础 |
SRE 实践:由于 HTTP/2 的多路复用,一个连接上的某个慢 RPC 可能影响同连接的其他 RPC。限流熔断时需考虑连接级隔离,例如为高优先级服务使用独立 Channel。