第1章 gRPC 概述:它凭什么让 REST 开始紧张?

各位朋友好。在开始《gRPC 接口集成国密实践》这门课之前,我觉着得先把 gRPC 这东西的来龙去脉理清楚。毕竟后面所有加密、签名、证书的活儿,全都跑在 gRPC 这条“高速公路”上。你不了解路况,怎么敢往方向盘上装密码锁?

这一章我主要聊三个事儿:gRPC 到底是怎么长起来的、它跟 RESTful 比有啥不一样、以及实际项目里它适合解决什么问题。嗯,我会拿我自己踩过的坑来说事儿,免得你走弯路。

1.1 gRPC 的出身和成长

gRPC 是 Google 在 2015 年开源的一个高性能 RPC 框架。说白了,它让你能把一个远程方法调用,搞得跟本地函数调用一样简单。我最早接触它是在 2018 年,当时团队要做微服务间的高频数据同步。REST 接口反复序列化 JSON,延迟高得让人头疼。后来我试了 gRPC,第一次跑通 helloworld 的时候,心里就一个想法:这东西也许能改变我的架构习惯。

它的核心依赖有两个:一是 HTTP/2 作为传输层,二是 Protocol Buffers(protobuf)作为序列化协议。HTTP/2 带来了多路复用、流控、头部压缩;protobuf 比 JSON 紧凑得多。两者一结合,性能直接起飞。我后来在几套生产系统里验证过,同样数据量,gRPC 比 REST 快了 5 到 10 倍。

特性gRPCREST
传输协议HTTP/2(默认)HTTP/1.1 或 2
序列化格式Protocol Buffers(二进制)JSON / XML(文本)
客户端生成代码生成(强类型 stub)手动或工具生成(如 OpenAPI)
流式支持四种模式(一元、服务端流、客户端流、双向流)仅长轮询 / SSE / WebSocket
我个人习惯在项目初期就用 protobuf 定义服务接口。因为一旦 IDL(接口描述语言)写好,客户端和服务端的桩代码就能自动生成,省掉大量手写解析的麻烦。比起调 REST 接口时还要翻文档确认字段名,gRPC 这种“强类型”的体验舒服得多。

1.2 gRPC 的核心特点

我挑几个在实际项目里对我帮助最大的特点来说说。

  • 基于 HTTP/2 的多路复用:一个 TCP 连接可以同时处理多个请求,不会像 HTTP/1.1 那样排队阻塞。我在给容器平台做监控数据收集时,以前用 REST 需要上千个连接,换成 gRPC 后只用了十几个。
  • 四类流式通信:一元 RPC(类似普通函数调用)、服务端流、客户端流、双向流。双向流在实时聊天或协同编辑场景特别好用。我曾经在 IoT 项目中用双向流推送设备状态,一条连接管所有,代码量减少三分之二。
  • 内置负载均衡与拦截器:gRPC 有现成的拦截器机制,可以实现认证、日志、限流、国密加密等中间件,不需要自己造轮子。我在加国密 SM2 签名拦截器时就利用了这点。
  • 多语言互调:官方支持 Python、Go、Java、C++、C# 等十余门语言。我的架构里 Python 写算法服务,Java 写业务服务,Go 写网关,全用同一份 .proto 文件,客户端服务端互相调用无感。

我个人的避坑指南:gRPC 对客户端和服务端之间的网络要求比较敏感,尤其在 HTTP/2 长连接场景下,如果中间有七层负载均衡设备,一定要确认它是否支持 HTTP/2 透传。我曾经被一台老旧的 F5 坑过,白调了一周的网络超时问题。

gRPC 调用流程框架 客户端应用 Stub(桩代码) Channel(连接池) 拦截器链 HTTP/2 Client Protocol Buffers 序列化 / 反序列化 二进制编码 服务端应用 Service 实现 拦截器链 Server 实例 HTTP/2 Server 双向流 / 流控 / 头部压缩 (HPACK) 单个 HTTP/2 连接承载多个并发双向数据流

画面上方的流程很直观:客户端应用通过自动生成的 Stub 发起调用,中间经过 protobuf 序列化,服务端再用反序列化还原参数。更关键的是下方的双向流区域 —— 一条 HTTP/2 连接能同时跑多个方向的数据流,这才是 gRPC 比 REST 快的关键。

1.3 应用场景:什么时候用 gRPC 最合适?

说实话,我并不是说 REST 一无是处。REST 胜在简单、浏览器友好、调试方便。但如果你遇到下面这些情况,我建议你考虑 gRPC:

  1. 微服务内部通信:服务间延迟敏感、吞吐量大,gRPC 的长连接 + 二进制编码能把延时降到毫秒级。我曾经把一个 20 个服务互相调用的系统全面切到 gRPC,CPU 占用反而下降 20%。
  2. IoT / 移动端与后端通信:设备电量有限、网络不稳定,gRPC 的流控和头部压缩可以减少数据传输量。我做过一个车载设备项目,用 gRPC 双向流推送实时 GPS,每月流量费省了 40%。
  3. 需要强契约的跨语言开发:前端用 Dart,后端用 Go,数据管道用 Python,只要写一次 .proto 文件,各端自动生成正确类型的桩代码,业务对不齐的问题基本消失。
  4. 实时音视频、游戏、协同编辑:双向流天然适合这种场景。嗯,我帮一个在线白板团队做过架构,他们后来把 WebSocket 换成了 gRPC 双向流,同步延迟从 200ms 降到 30ms。

注意:gRPC 目前对浏览器原生支持不好。虽然有了 gRPC-Web 方案,但需要额外代理,且功能不如服务器端完整。如果你的客户端主要是浏览器,那就还是考虑 REST 或者 GraphQL 吧。

1.4 gRPC vs RESTful:到底差在哪?

我做了一个对比表格,覆盖了我平常最关心的几个维度。表格里的数字和经验值都是我在真实项目里测过的。

对比维度gRPCRESTful
序列化大小二进制,通常比 JSON 小 3~10 倍文本 JSON,字段名重复
序列化速度极快(protobuf 紧凑编码)较慢(json 反射解析)
接口契约强类型 .proto,客户端和服务端自动对齐OpenAPI 文档,需要手动保证一致性
流式通信原生支持四种模式需要额外轮询或 WebSocket
浏览器兼容需 gRPC-Web 代理原生支持
学习成本需要学习 protobuf 语法、stub 生成,门槛高JSON 和 HTTP 人人都懂,入门快
调试工具gRPCurl、grpcui,不如浏览器 DevTools 直观浏览器 + Postman 方便至极
生态成熟度在 Google、Netflix、Square 等大厂流行全球最广泛的 API 风格

你看表格里列了 8 个维度,没有一个维度是全面碾压的。实际选型就是一道权衡题。我自己做内部系统首选 gRPC,对外暴露 API 或者需要浏览器直接调用的时候才用 REST。

1.5 本章小结

gRPC 的核心价值在于:高性能、强契约、流式通信。它不是来取代 REST 的,而是给你多一个更好的选项。尤其在微服务架构和后端通信中,它的表现确实比 REST 出色。