gRPC 含义
gRPC 是一个功能强大的开源 RPC(远程过程调用)框架,用于构建可扩展且高性能的 API。它使客户端与服务器应用程序能够透明地通信,并构建互联的系统。许多领先的科技公司(如 Google、Netflix、Square、IBM、Cisco 和 Dropbox)都已采用 gRPC。该框架基于 HTTP/2、Protocol Buffers(协议缓冲区) 等现代技术栈,以确保 API 在安全性、性能和可扩展性方面达到最优。
gRPC 的历史
gRPC 由 Google 于 2015 年开发,最初作为其内部 RPC 框架的延伸,旨在连接使用不同技术构建的众多微服务。起初,gRPC 与其内部基础设施紧密相关,但随后被开源并标准化,供社区广泛使用。在其发布的第一年内,就被多家顶级组织用于从微服务到 Web、移动和物联网(IoT)等多种场景。2017 年,由于其日益增长的影响力,gRPC 被纳入 云原生计算基金会(CNCF) 的孵化项目。
gRPC 基础概念
gRPC 的成功离不开一系列领先技术的支持,这些技术在性能和安全性方面远超传统的 JSON 和 XML。其主要优势源于以下几个核心概念:
协议缓冲区(Protocol Buffers)
Protocol Buffers(简称 Protobuf)是 Google 开发的一种序列化/反序列化协议,可用于轻松定义服务并自动生成客户端库。gRPC 使用 Protobuf 作为其 接口定义语言(IDL) 和序列化工具集。当前最新版本为 proto3,功能更丰富且更易于使用。
gRPC 的服务和消息通过 .proto 文件定义。Protobuf 编译器 protoc 会根据 .proto 文件生成客户端和服务器端代码。运行时,这些代码将 .proto 文件加载到内存中,并利用内存中的 schema 对二进制消息进行序列化/反序列化。生成代码后,客户端与远程服务之间即可交换消息。

Protobuf 相较于 JSON 和 XML 具有显著优势:
- 更小的消息体积:数据以二进制格式编码,占用空间更少。
- 更低的 CPU 开销:解析效率更高,尤其适合 CPU 性能较弱的设备(如移动设备)。
- 更快的传输速度:轻量级消息使得通信更迅速。
流式传输(Streaming)
流式传输是 gRPC 的另一关键特性,允许在单个请求中完成多个操作。这得益于 HTTP/2 的 多路复用(multiplexing) 能力——即在单个 TCP 连接上同时发送多个请求或接收多个响应。
gRPC 支持以下几种流式 RPC 类型:
- 服务器流式 RPC(Server-streaming RPCs):客户端发送一个请求,服务器返回一个数据流。消息顺序保持不变,直到所有数据发送完毕。
- 客户端流式 RPC(Client-streaming RPCs):客户端发送一个数据流,服务器处理后返回单个响应。gRPC 保证单次 RPC 调用内消息的顺序。
- 双向流式 RPC(Bidirectional-streaming RPCs):客户端与服务器各自独立地发送消息流。虽然两个流相互独立、可异步发送,但各自内部的消息顺序仍被保留。
HTTP/2
gRPC 构建于 HTTP/2 之上。HTTP/2 于 2015 年发布,旨在克服 HTTP/1.1 的诸多限制。尽管兼容 HTTP/1.1,HTTP/2 引入了多项先进特性:
- 二进制分帧层(Binary Framing Layer):将请求/响应拆分为小的二进制帧,提升传输效率,并支持无阻塞的多路复用。
- 全双工流式传输(Streaming):客户端与服务器可同时发送和接收数据。
- 流量控制(Flow Control):精细控制内存中缓冲的消息量。
- 头部压缩(Header Compression):使用 HPACK 算法仅传输与前一个头部不同的部分,大幅减少开销。
- 同步与异步处理支持:gRPC 可灵活支持不同类型的交互和流式 RPC。
这些特性使 gRPC 在云环境中资源占用更少、响应更快,同时延长移动设备的电池寿命。
通道(Channels)
通道是 gRPC 的核心概念之一。HTTP/2 支持在单个连接上并发多个流,而 通道 则进一步扩展此能力,支持跨多个并发连接管理多个流。通道用于指定服务器地址和端口,是创建客户端存根(stub)的基础。
gRPC 架构
下图展示了典型的 gRPC 架构,包含客户端与服务器两部分:

- 客户端包含一个 存根(stub)(由
.proto文件自动生成),类似于一个接口,定义了可用的远程过程。 - 客户端调用本地存根方法,并传入参数。
- 存根使用 Protobuf 对参数进行 序列化(marshaling),并通过本地客户端运行时库发送请求。
- 操作系统通过 HTTP/2 协议 将请求发送至远程服务器。
- 服务器操作系统接收数据包,并调用服务器端存根。
- 服务器存根使用 Protobuf 反序列化 参数,执行对应的服务逻辑。
- 执行结果被再次序列化,并通过传输层返回给客户端。
- 客户端存根接收响应,反序列化结果,并将控制权交还给调用者。
gRPC 的优势
gRPC 在传统 RPC 设计基础上进行了现代化革新,具备以下显著优势:
1. 高性能
- 相比 REST + JSON,gRPC 性能可提升 高达 10 倍。
- Protobuf 生成紧凑的二进制消息,序列化/反序列化速度快。
- HTTP/2 提供 多路复用、头部压缩、服务器推送 等机制,消除队头阻塞,提升吞吐量。
2. 原生流式支持
- 支持四种通信模式:
- 一元调用(Unary)
- 客户端流式
- 服务器流式
- 双向流式
- 流式语义直接内置于服务定义中,简化实时通信开发。
3. 自动生成代码
- 使用
protoc编译器从.proto文件自动生成:- 服务端骨架(skeleton)
- 客户端存根(stub)
- 大幅减少样板代码,提升开发效率,尤其适用于多服务架构。
4. 跨平台互操作性
- 官方支持多种语言:Java、JavaScript、Python、Go、C#、Ruby、Dart、Objective-C 等。
- Protobuf 的二进制格式与高效代码生成机制,确保跨语言、跨平台的高性能通信。
5. 安全性
- 默认通过 TLS/SSL 加密通信,确保端到端安全。
- 支持身份认证与数据加密,符合现代 API 安全标准。
6. 易用性与生产力
- 提供完整的 RPC 解决方案,开箱即用。
- 自动化工具链减少手动编码,开发者可聚焦业务逻辑。
7. 内置高级功能
- 原生支持:
- 元数据交换
- 超时与取消机制
- 拦截器(Interceptors)
- 负载均衡
- 服务发现
- 认证与授权等
gRPC 的劣势
尽管优势明显,gRPC 也存在一些局限性:
1. 浏览器支持有限
- 由于依赖 HTTP/2,无法直接从浏览器调用 gRPC 服务。
- 需借助 gRPC-Web 和代理层(如 Envoy)将 HTTP/1.1 转换为 HTTP/2。
2. 非人类可读格式
- Protobuf 消息为二进制格式,不可直接阅读或调试。
- 需要额外工具(如
grpc_cli)来分析网络流量、构造请求或排查问题。
3. 不支持边缘缓存
- gRPC 调用通常使用 HTTP POST 方法,无法被 CDN 或代理缓存。
- 协议本身未定义缓存语义,不利于内容分发优化。
4. 学习曲线较陡
- 开发者需掌握 Protobuf 语法、HTTP/2 机制及 gRPC 工具链。
- 相比 REST,入门门槛更高,团队适应成本较大。
gRPC 与 REST 对比
gRPC 并非 REST 的替代品,而是一种适用于特定场景的 高性能替代方案:
| 特性 | gRPC | REST |
|---|---|---|
| 协议 | HTTP/2 | HTTP/1.1(通常) |
| 数据格式 | Protobuf(二进制) | JSON/XML(文本) |
| 性能 | 极高(低延迟、小体积) | 中等 |
| 流式支持 | 原生支持 | 需 WebSocket 或 SSE |
| 浏览器支持 | 需 gRPC-Web 代理 | 原生支持 |
| 可读性 | 差(需工具解析) | 好(人类可读) |
| 适用场景 | 微服务、IoT、移动端、内部系统 | 公开 API、Web 前端、通用集成 |
结论:若需构建高性能、低延迟的内部微服务通信,gRPC 是理想选择;若面向公众或 Web 前端,REST 仍是更稳妥的方案。
结论
多年来,gRPC 因其高速、高效的特性,在微服务架构中广受欢迎。然而,它也带来了新的安全挑战——如内容验证、身份认证、授权等。由于消息为二进制格式,安全检测需先解码,增加了复杂性。
建议:
- 遵循 OWASP API 安全 Top 10,制定 gRPC 应用的安全防护策略。
- 部署支持 gRPC 的 运行时 API 安全层,在不增加成本的前提下,有效应对 gRPC 特有的安全风险。