1. gRPC 概述
1.1 gRPC 是什么
gRPC 是 Google 开源的高性能、跨语言远程过程调用(RPC)框架,基于 HTTP/2 协议传输,使用 Protocol Buffers(protobuf) 作为接口定义语言(IDL)和序列化工具。它允许客户端像调用本地函数一样直接调用另一台机器上的服务方法,屏蔽了网络通信、序列化、反序列化等底层细节。
核心定义:gRPC = HTTP/2 传输 + Protobuf 序列化 + 服务契约驱动。
gRPC 的通信模型支持四种模式:
- 一元 RPC(Unary RPC):客户端发送单个请求,服务端返回单个响应,类似传统 HTTP 请求-响应。
- 服务端流式 RPC(Server Streaming RPC):客户端发送单个请求,服务端返回一个消息流。
- 客户端流式 RPC(Client Streaming RPC):客户端发送一个消息流,服务端返回单个响应。
- 双向流式 RPC(Bidirectional Streaming RPC):双方独立发送和接收消息流,可实时交互。
1.2 gRPC 与 REST 对比
REST 是当前最流行的 API 设计风格,而 gRPC 在微服务、高性能场景下逐渐成为首选。两者在协议、数据格式、性能、开发体验等方面存在显著差异:
| 对比维度 | gRPC | REST |
|---|---|---|
| 传输协议 | HTTP/2(多路复用、双向流、头部压缩) | HTTP/1.1(串行请求、单向流) |
| 数据格式 | Protocol Buffers(二进制,紧凑高效) | JSON / XML(文本,冗余大) |
| 接口定义 | 契约驱动(.proto 文件强制定义) | 约定驱动(文档或代码注释) |
| 流式通信 | 原生支持四种流式模式 | 需额外实现 WebSocket / SSE |
| 性能 | 高(二进制序列化 + HTTP/2 多路复用) | 中(文本序列化 + HTTP/1.1 队头阻塞) |
| 浏览器支持 | 需 gRPC-Web 代理 | 原生支持 |
| 工具生态 | protoc 编译器、反射、拦截器 | Swagger / OpenAPI、Postman |
| 适用场景 | 微服务内部通信、实时流、IoT | 公开 API、Web 应用、浏览器端 |
选型建议:内部微服务间通信优先选择 gRPC,追求高性能和强契约;对外公开 API 或需要浏览器直接访问时,REST 仍是更成熟的选择。gRPC-Web 可弥补浏览器端短板,但会增加架构复杂度。
1.3 gRPC 核心优势
gRPC 在微服务架构中具备以下不可替代的核心优势:
- 高性能传输:基于 HTTP/2 多路复用,单个连接可并行处理多个请求,消除队头阻塞;二进制 Protobuf 序列化比 JSON 快 3~10 倍,体积减少 60%~80%。
- 强契约驱动:.proto 文件是服务接口的唯一真相来源(Single Source of Truth),自动生成客户端和服务端桩代码,避免接口不一致问题。
- 多语言互操作性:支持 C++、Go、Java、Python、Ruby、C#、Node.js 等 10+ 语言,跨语言调用无需额外适配层。
- 原生流式通信:服务端流、客户端流、双向流三种模式,适合实时推送、大数据分片、聊天等场景。
- 内置安全机制:天然支持 TLS/SSL 加密,结合拦截器可实现认证、授权、审计日志等安全能力。
- 完善的拦截器链:支持客户端和服务端拦截器,可统一处理日志、监控、限流、重试、熔断等横切关注点。
1.4 gRPC 典型应用场景
gRPC 在以下场景中展现出显著优势,已成为现代云原生架构的关键组件:
| 场景 | 说明 | 典型示例 |
|---|---|---|
| 微服务内部通信 | 服务间高频、低延迟调用,要求强契约和跨语言支持 | 订单服务调用库存服务、用户服务 |
| 实时数据流处理 | 需要服务端推送或双向实时交互 | 股票行情推送、物联网设备数据上报 |
| 移动端与后端通信 | 低带宽、高延迟网络下需要高效序列化 | 移动 App 获取用户信息、上传日志 |
| 多语言异构系统集成 | 不同技术栈团队协作,需统一接口契约 | Go 后端 + Python 数据科学 + Java 中间件 |
| 云原生基础设施 | Kubernetes、Envoy、etcd 等核心组件原生支持 gRPC | K8s API 扩展、服务网格数据面通信 |
| 高性能网关/代理 | 需要低开销、高吞吐的代理转发 | Envoy 代理 gRPC 流量、gRPC 负载均衡 |
注意:gRPC 不适合浏览器直接调用(需 gRPC-Web 代理)、不适合超轻量级单次请求(连接建立开销相对较大)、不适合需要人类可读调试的公开 API(二进制协议不易直接查看)。