1. gRPC 基础概念
1.1 gRPC 是什么
gRPC 是 Google 开源的高性能、跨语言远程过程调用(RPC)框架,基于 HTTP/2 协议传输,默认使用 Protocol Buffers 作为接口定义语言(IDL)与序列化工具。它让客户端应用能像调用本地函数一样直接调用另一台机器上的服务端方法,屏蔽了网络通信、序列化、反序列化等底层细节。
核心特征: 强类型契约驱动、双向流支持、多语言互操作、高性能二进制传输。
1.2 gRPC vs REST:关键对比
| 对比维度 | gRPC | REST |
|---|---|---|
| 传输协议 | HTTP/2(多路复用、头部压缩) | HTTP/1.1 或 HTTP/2 |
| 数据格式 | Protocol Buffers(二进制,紧凑高效) | JSON / XML(文本,冗余较大) |
| 接口定义 | .proto 文件强类型契约 |
OpenAPI / 手动文档约定 |
| 调用方式 | 一元、服务端流、客户端流、双向流 | 请求-响应(支持 SSE 流) |
| 浏览器支持 | 需 gRPC-Web 代理 | 原生支持 |
| 适用场景 | 微服务间通信、低延迟、流式处理 | Web API、资源导向接口 |
选型建议: 内部微服务调用优先选 gRPC;对外公开 API 或需要浏览器直接访问时,REST 仍是更成熟的选择。
1.3 Protocol Buffers 简介
Protocol Buffers(简称 protobuf)是 Google 的语言中立、平台中立的结构化数据序列化机制。通过 .proto 文件定义消息结构和服务接口,然后使用 protoc 编译器生成目标语言代码。
syntax = "proto3";
package order.v1;
// 订单服务定义
service OrderService {
rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse);
}
// 创建订单请求
message CreateOrderRequest {
string user_id = 1;
repeated string item_ids = 2;
double total_amount = 3;
}
// 创建订单响应
message CreateOrderResponse {
string order_id = 1;
int32 status_code = 2;
string status_message = 3;
}
protobuf 优势: 序列化体积约为 JSON 的 1/3,速度提升 3~10 倍;字段编号(field number)保证向后兼容;自动生成强类型代码,减少手写错误。
1.4 gRPC 四大服务类型
gRPC 基于 HTTP/2 的流式能力,定义了四种服务方法模式,覆盖从简单请求-响应到实时双向通信的全部场景。
- 一元 RPC(Unary RPC): 客户端发送一个请求,服务端返回一个响应。与普通函数调用语义一致。
- 服务端流 RPC(Server Streaming RPC): 客户端发送一个请求,服务端返回一个消息流。适用于推送日志、批量查询结果等场景。
- 客户端流 RPC(Client Streaming RPC): 客户端发送一个消息流,服务端返回一个响应。适用于上传文件、批量提交数据等场景。
- 双向流 RPC(Bidirectional Streaming RPC): 客户端和服务端各自独立发送消息流,双方可同时读写。适用于实时聊天、游戏同步、协同编辑等场景。
1.5 服务类型选择矩阵
| 业务场景 | 推荐服务类型 | 选择理由 |
|---|---|---|
| 查询单个用户信息 | 一元 RPC | 请求-响应模型,语义简单直接 |
| 订阅实时股票价格 | 服务端流 RPC | 服务端持续推送,客户端被动接收 |
| 上传大文件分片 | 客户端流 RPC | 客户端分块发送,服务端合并处理 |
| 多人实时白板协作 | 双向流 RPC | 双方独立收发,低延迟同步 |
| 批量提交订单后等待确认 | 客户端流 RPC | 流式提交 + 单次确认响应 |
常见误区: 不要把所有 RPC 都定义为一元模式。流式 RPC 在大量数据或实时场景下能显著降低延迟和内存开销,但需要合理处理背压(backpressure)和连接生命周期。