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 的流式能力,支持四种通信模式。理解每种模式的流量特征,是设计限流熔断策略的前提。

gRPC 四种通信模式对比 Unary RPC 客户端发送 1 个请求 服务端返回 1 个响应 类似传统 HTTP API 最常用、最易限流 Server Streaming 客户端发送 1 个请求 服务端返回 N 个响应 适用:订阅、日志推送 限流需关注消息速率 Client Streaming 客户端发送 N 个请求 服务端返回 1 个响应 适用:批量上传、文件 限流需关注请求总量 Bidirectional 客户端发送 N 个请求 服务端返回 M 个响应 适用:实时聊天、游戏 限流最复杂、双向控制 限流熔断设计要点(按通信模式) • Unary:按请求数(QPS)限流,熔断基于错误率或延迟。 • Server Streaming:除 QPS 外,需限制每条流的最大消息数或总字节数,防止慢消费。 • Client Streaming:限制客户端单次流的最大消息数或总大小,防止内存溢出。 • Bidirectional Streaming:双向流需同时控制发送和接收速率,熔断需考虑流生命周期。 • 通用原则:所有流式 RPC 都应设置 deadline,避免无限等待导致连接泄漏。

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。