2. gRPC 基础:定义、Protocol Buffers 与四种通信模式

在微服务链路中,gRPC 是承载远程调用的核心协议。理解其底层定义、序列化机制与通信模式,是配置超时重试与排查故障的前提。本节从三个维度建立基础认知。

2.1 gRPC 定义与核心特性

gRPC 是一个高性能、开源的远程过程调用(RPC)框架,由 Google 开发并基于 HTTP/2 协议传输。它默认使用 Protocol Buffers 作为接口定义语言(IDL)与序列化工具,支持双向流、流量控制与多路复用。

特性 说明 对超时重试的影响
HTTP/2 多路复用 单一 TCP 连接可承载多个并发流 减少连接建立开销,但超时需按流粒度控制
Protocol Buffers 强类型、二进制序列化,体积小、解析快 序列化/反序列化耗时稳定,便于预估超时基线
双向流 客户端与服务端可同时发送多条消息 流式场景的超时策略与一元调用不同
内置拦截器 支持客户端/服务端拦截器链 可在拦截器中统一注入超时与重试逻辑
关键认知: gRPC 的超时不是“连接超时”,而是“调用截止时间(Deadline)”。客户端设置 Deadline 后,服务端在超过该时间后主动取消上下文,避免资源悬空。

2.2 Protocol Buffers 简介

Protocol Buffers(简称 Protobuf)是 gRPC 的接口定义与序列化基础。开发者通过 .proto 文件定义服务接口和消息结构,然后使用 protoc 编译器生成目标语言的代码。

2.2.1 核心语法示例

syntax = "proto3";

package order.v1;

// 定义订单服务
service OrderService {
  rpc GetOrder (GetOrderRequest) returns (GetOrderResponse);
  rpc ListOrders (ListOrdersRequest) returns (stream Order);
}

// 请求消息
message GetOrderRequest {
  string order_id = 1;
  int32 timeout_ms = 2;  // 客户端建议超时
}

// 响应消息
message GetOrderResponse {
  string order_id = 1;
  string status = 2;
  repeated OrderItem items = 3;
}

message OrderItem {
  string sku = 1;
  int32 quantity = 2;
  double price = 3;
}

2.2.2 Protobuf 与 JSON 对比

维度 Protocol Buffers JSON
序列化格式 二进制 文本
数据体积 小(约 JSON 的 30%) 大
解析速度 快(无需字符串解析) 较慢
Schema 强制 强类型,编译期校验 弱类型,运行时校验
向后兼容 支持字段编号 + 可选/必选规则 需手动处理
故障排查提示: 当 gRPC 调用返回 Unimplemented 或 Internal 错误时,优先检查 .proto 文件版本是否与服务端一致。字段编号变更或 message 结构不匹配是常见根因。

2.3 gRPC 四种通信模式

gRPC 基于 HTTP/2 流提供了四种通信模式。不同模式对超时、重试与故障排查的影响差异显著。

gRPC 四种通信模式对比 ① 一元 RPC(Unary) 客户端发送 1 个请求 服务端返回 1 个响应 最常用,超时模型最简单 ② 服务端流 RPC 客户端发送 1 个请求 服务端返回多条消息(stream) 适用于日志推送、事件订阅 ③ 客户端流 RPC 客户端发送多条消息(stream) 服务端返回 1 个响应 适用于批量上传、数据聚合 ④ 双向流 RPC 双方独立发送多条消息 全双工通信 适用于实时聊天、协同编辑 超时与重试策略差异 • 一元 RPC:超时从请求发送开始计时,重试可整体重新发起 • 服务端流 RPC:超时覆盖整个流生命周期,重试需重新建立流 • 客户端流 RPC:超时从第一条消息开始,重试需重新发送所有消息 • 双向流 RPC:超时按消息粒度独立控制,重试逻辑最复杂

2.3.1 各模式超时配置要点

通信模式 Deadline 设置位置 重试粒度 常见故障场景
一元 RPC 客户端调用前设置 withDeadline() 整个调用 服务端处理慢、网络抖动
服务端流 流创建时设置,流内不可变 整个流 服务端中途挂掉、流中断
客户端流 流创建时设置,流内不可变 整个流 客户端发送超时、服务端不响应
双向流 流创建时设置,流内不可变 按消息或按流 消息乱序、流关闭异常
常见误区: 在流式 RPC 中,Deadline 一旦设置,流内所有消息共享同一个截止时间。如果某条消息处理时间过长,可能导致后续消息被提前取消。建议在业务层面为每条消息设置独立的超时监控,而非依赖 Deadline 兜底。

2.4 本章小结

  • gRPC 核心:基于 HTTP/2 与 Protobuf 的高性能 RPC 框架,Deadline 机制是超时控制的基础。
  • Protobuf 作用:强类型 IDL + 高效二进制序列化,版本一致性是故障排查的关键点。
  • 四种通信模式:一元、服务端流、客户端流、双向流,各自超时与重试策略不同,需按场景选择。