1. gRPC 概述:从一次"翻车"说起
先聊点实在的。gRPC 是什么?简单说,是 Google 开源的一个高性能远程过程调用框架。但我更喜欢这么理解:它让你写代码时感觉像在调本地函数,实际却跨了网络。
我第一次接触 gRPC 是在做一个微服务改造项目。当时团队用 REST 接口,每个服务间通信都自己拼 JSON、解析 JSON,出个字段变更就得改三四个地方。后来有个同事说:「试试 gRPC 吧」。说实话,我一开始是抗拒的——又要学新工具。但用下来,嗯,真香。
传统 RPC 和 REST,有什么问题?
先看传统 RPC。很多自研 RPC 框架走二进制协议,快是快,但耦合紧。服务端和客户端得用同一个语言、同一套序列化库,换语言就得重写。我参与过一个老项目,服务用 Java,客户端用 C++,两边对数据结构的定义不同,线上出了好几次诡异 bug。
再看 REST。REST 的好处是通用、简单,谁都能看懂 HTTP 请求。但代价也很明显:
- 序列化开销大:JSON 文本格式,解析慢,体积大。我记得压测时,纯 JSON 序列化能吃掉 30% 的 CPU。
- 没有强类型约束:接口文档写的是字符串,实际传过来的是个数字,运行时才报错。我在生产上踩过这个坑——前端传了个字段类型不对,后端解析炸了,排查花了两小时。
- 只支持请求-响应模式:想做个服务端推送?得靠 WebSocket 或轮询,折腾。
gRPC 的三板斧
gRPC 之所以能解决上述痛点,靠的是三个核心武器:HTTP/2、Protocol Buffers、双向流。下面逐个说。
1. HTTP/2:多路复用与头部压缩
传统 HTTP/1.1 有个问题:同一个连接上,请求必须排队。一个请求没响应完,后面的得等着。这就是队头阻塞。HTTP/2 引入了多路复用——多个请求共用一条 TCP 连接,互不干扰。
gRPC 底层强制使用 HTTP/2。这意味着你的客户端和服务端之间可以同时发送多个 RPC 调用,而不用建多个连接。另外,HTTP/2 还做了头部压缩(HPACK),省带宽。我在项目里实测过,同样一组接口,从 REST/HTTP/1.1 改成 gRPC,传输数据量减少了 50% 以上,尤其是头部反复传递的场景——比如认证 。
2. Protocol Buffers:紧凑、强类型的契约
Protocol Buffers(简称 protobuf)是 Google 的序列化框架,也是 gRPC 的默认序列化方式。它不是 JSON 那样靠 key-value 文本标记,而是用二进制编码,紧凑到极致。
举个例子——定义一个用户信息结构:
syntax = "proto3";
message User {
int32 id = 1;
string name = 2;
string email = 3;
}
编译生成对应的客户端和服务端代码。关键好处:
- 字段有编号,传输时只传编号和值,不传字段名。而 JSON 每次都把 "name" 这个字符串传一遍。
- 类型在编译时就固定了。如果你传了个字符串给 int32 字段,编译直接报错,不会等到运行时崩。
- 版本兼容容易:新增字段不用改老代码,老客户端看到未知字段就跳过。
3. 双向流:不止是请求-响应
REST 的模型是客户端发请求,服务端回响应,一个来回就结束。gRPC 支持四种调用模式:
| 模式 | 描述 | 适用场景 |
|---|---|---|
| 一元 RPC | 客户端发一个请求,服务端回一个响应 | 普通查询、写入 |
| 服务端流式 RPC | 客户端发一个请求,服务端回多个响应(流) | 批量查询、日志推送 |
| 客户端流式 RPC | 客户端发多个请求(流),服务端回一个响应 | 文件上传、批量提交 |
| 双向流式 RPC | 客户端和服务端各自独立发送流,全双工 | 聊天、实时协同、视频信令 |
双向流是我个人最喜欢的功能。比如一个实时监控面板:服务端持续推送 CPU 指标,客户端同时可以发送配置变更命令,双方互不等待。这在 REST 体系里很麻烦,要么轮询,要么 WebSocket + 额外协议。
gRPC 与传统 RPC/REST 对比总结
| 维度 | 传统 RPC | REST | gRPC |
|---|---|---|---|
| 传输协议 | 自定义 TCP/UDP | HTTP/1.1 | HTTP/2 |
| 序列化格式 | 二进制(私有) | JSON/XML | Protocol Buffers |
| 接口契约 | 无或文档 | Swagger 等 | .proto 文件(强类型) |
| 流式支持 | 通常不支持 | 需额外方案 | 原生支持四种模式 |
| 性能(参考) | 高 | 中等 | 高 |
| 跨语言能力 | 弱 | 强 | 强(protoc 生成多语言) |
看到表格,你可能想问:gRPC 比 REST 快在哪?我做过一个压测,同样的业务逻辑,gRPC 的 QPS 比 REST(HTTP/1.1 + JSON)高了 3-5 倍,延迟也少 40% 以上。但注意,这主要是指内部服务间调用。如果面向浏览器客户端,REST 依然是主流,因为浏览器 HTTP/2 对 gRPC 的支持还不完整。
gRPC 知识体系一览
下面这张图概括了本章的核心逻辑:gRPC 如何把「定义契约」「生成本地代码」「网络传输」串联起来。你看一遍应该就能理解全貌。
你看,整个流程非常干净:定义一份 .proto 文件,然后 protoc 自动生成服务端和客户端的存根代码,两边各自实现或调用。底层传输由 gRPC 框架搞定,开发者几乎不用手动拼字节流。
好了,关于 gRPC 是什么、它和传统方案有什么不一样,以及它的三大核心特性,就讲到这里。我个人觉得,gRPC 最大的价值不是速度快,而是让微服务之间的「契约」变得显性、可编译、可验证。这在多人协作的大项目里,能省掉大量沟通和排错成本。希望你对它有个整体的感觉,后面章节我们会一步步搭环境、写第一个 .proto、跑通一个完整的 RPC 调用。