一、gRPC 概述
1.1 gRPC 到底是什么
先问个问题:你做过微服务间的接口联调吗?
传统做法是写 RESTful API,JSON 来 JSON 去,接口文档靠 Swagger 同步。但实际跑起来,坑不少——序列化慢、类型不严格、流式推送要自己折腾 WebSocket。
gRPC 就是 Google 为了解决这堆问题推出的远程调用框架。它基于 HTTP/2,用 Protocol Buffers(简称 protobuf)做序列化协议。你定义好 .proto 文件,工具就能自动生成客户端和服务端代码。
说白了,gRPC 让你像调用本地函数一样调用远程服务。调用方不用关心网络细节,服务方只需要实现接口。我在项目中第一次用 gRPC 替换 REST,接口联调时间直接砍半——嗯,后期运维也省心很多。
- 强类型接口定义(.proto 文件)
- 基于 HTTP/2 多路复用
- 默认使用 protobuf 二进制序列化
- 支持四种通信模式
1.2 为什么要用 gRPC?——优势清单
我个人习惯用一句话总结:性能更好、类型更安全、流式能力原生。下面展开说说。
| 优势 | 说明 | 我经历过的场景 |
|---|---|---|
| 高性能序列化 | protobuf 二进制格式,比 JSON 小 3~10 倍,解析快一个数量级 | 某 IoT 项目,网关上报数据量每天 2 亿条,切到 gRPC 后带宽成本下降 50% |
| 强类型契约 | .proto 同时是接口文档、校验规则、代码生成源 | 联调时再也不出现「字段名写错但没报错」的尴尬 |
| 流式通信原生 | 支持服务端流、客户端流、双向流,天然解决推送场景 | 直播弹幕系统,直接复用 gRPC 双向流,省掉单独维护 WebSocket 集群 |
| 多语言互调 | 官方工具生成 C++/Java/Python/Go 等十几种语言代码 | 我负责的 Go 服务调 Python 认证中心,一个 .proto 两端用,无需手写 HTTP 客户端 |
1.3 HTTP/2 基础——gRPC 的传输基石
gRPC 为什么快?很大功劳在 HTTP/2。先看它和 HTTP/1.1 的差异。
| 特性 | HTTP/1.1 | HTTP/2 |
|---|---|---|
| 连接复用 | 一个连接只能发一个请求(Pipeline 有队头阻塞) | 多路复用,一个连接同时处理多个请求 |
| 数据格式 | 纯文本行 + 头部明文 | 二进制分帧,头部压缩(HPACK) |
| 优先级 | 无原生优先级 | 支持流优先级和依赖 |
| 服务器推送 | 不支持 | 服务端可主动推送资源 |
多路复用是核心。一次连接可以建立多个流(Stream),每个流对应一个 gRPC 调用。流之间独立传输,不会互相阻塞。举个例子:你同时调用 UserService.GetProfile 和 OrderService.ListOrders,HTTP/2 把它们放在同一条 TCP 连接里交错传输,省掉三次握手和 TLS 握手的开销。
我曾经踩过一个坑:HTTP/1.1 下客户端为了并发开了几十个连接,每个连接都做 TLS 握手,CPU 直接飙满。切到 gRPC + HTTP/2 后,连接数降到个位数,资源开销大幅降低。
// 一个典型的 gRPC 调用在 HTTP/2 帧层面的表现:
// 帧类型: HEADERS, DATA, SETTINGS, PING, GOAWAY
// Stream ID: 每个 gRPC 调用分配唯一 ID
// 流标识: 1 表示客户端 -> 服务端,0 表示服务端 -> 客户端
1.4 gRPC vs REST——实战对比
很多新人会问:现在 REST 不是挺好的吗?为什么要换?我一般用这张表回答:
| 对比维度 | REST (HTTP/1.1 + JSON) | gRPC (HTTP/2 + Protobuf) |
|---|---|---|
| 接口定义 | 手工文档 / OpenAPI | .proto 文件,自动生成 |
| 数据类型 | 动态类型,运行时需校验 | 静态强类型,编译期检查 |
| 序列化性能 | JSON 文本,慢且大 | Protobuf 二进制,快且小 |
| 流式支持 | 需额外实现(SSE/WebSocket) | 原生支持四种流模式 |
| 浏览器兼容 | 完美支持 | 需 gRPC-Web 或代理 |
| 工具链成熟度 | 大量 HTTP 调试工具 | 需要 grpcurl、evans 等专用工具 |
什么时候该选 gRPC?
- 微服务之间内部调用——延迟敏感、流量大的场景
- 需要强类型契约和代码生成——团队规模大,接口变更频繁
- 涉及流式数据——实时推送、日志收集、大文件分片
什么时候还是用 REST 吧?
- 对外暴露 API,客户端是浏览器或移动 App(无 gRPC-Web 支持时)
- 团队对 protobuf 不熟悉,严重依赖可视化调试
- 简单的 CRUD 操作,REST 已经足够
1.5 知识体系总览
下面这张图概括了本章的核心知识点及其关系。你可以把它当作后续学习的导航地图。