一篇读懂 gRPC:HTTP/2、Protobuf 与四种通信模式

gRPC 是微服务间通信的高性能框架:它基于 HTTP/2 协议的多路复用与流式传输,用 Protobuf 作为接口定义语言(IDL)与序列化格式,支持四种通信模式。与 REST 的 JSON over HTTP/1.1 相比,gRPC 在性能、类型安全与流式支持上有明显优势——但它不是 REST 的替代品,两者适用于不同的场景。本篇讲清 gRPC 的技术底座与选型框架。

技术底座:HTTP/2 与 Protobuf 的组合

HTTP/2 的三个关键特性为 gRPC 提供了传输层基础。多路复用(multiplexing)——多个请求共享一个 TCP 连接,不需要像 HTTP/1.1 那样开多条连接(消除队头阻塞的网络层版本——应用层的队头阻塞仍存在,HTTP/3 的 QUIC 协议解决网络层的);二进制分帧——HTTP/2 将报文拆为二进制帧,解析效率远高于文本格式的 HTTP/1.1;头部压缩(HPACK)——减少重复头部(如 Cookie、User-Agent)的传输开销。Protobuf(Protocol Buffers)是 gRPC 的序列化格式:用 .proto 文件定义接口与消息结构,编译器自动生成多语言的客户端与服务端代码——强类型接口是 gRPC 相对于 REST 的最大差异之一(REST 的 OpenAPI 规范是可选的,Protobuf 的类型定义是强制的)。Protobuf 的序列化效率远高于 JSON:二进制编码(体积小 3-10 倍),编解码速度快,且 schema 演进支持前后向兼容。

四种通信模式:Unary、Server Streaming、Client Streaming、Bidirectional

Unary(一元调用):客户端发一个请求、服务端返一个响应——与传统 HTTP 请求-响应模式相同,最常用的形态。Server Streaming(服务端流):客户端发一个请求,服务端返回一串消息(流式返回)——适用场景:LLM 的 SSE 流式输出(本库有专篇)、大文件的分块下载、实时推送的通知流。Client Streaming(客户端流):客户端发送一串消息,服务端返回一个响应——适用场景:批量上传(日志批量上报、传感器数据推送)、文件分块上传。Bidirectional Streaming(双向流):客户端与服务端同时收发消息流——适用场景:实时聊天、实时协作编辑、游戏的状态同步。四种模式的选择取决于交互的对称性与数据量:一次请求一次响应用 Unary,服务端持续推送用 Server Streaming,客户端持续发送用 Client Streaming,双方实时交互用 Bidirectional——gRPC 的流式能力是 REST 做不到的(HTTP 的 SSE 只是单向流)。

gRPC vs REST:性能、生态与选型

维度 gRPC REST
协议 HTTP/2 强制 HTTP/1.1 或 HTTP/2
序列化 Protobuf(二进制,紧凑) JSON(文本,可读)
类型安全 强制(proto 编译时检查) 可选(OpenAPI 规范)
流式支持 四种模式原生支持 SSE(仅服务端流)/ WebSocket
浏览器支持 需要 gRPC-Web 代理 原生支持
学习成本 需学 Protobuf IDL 几乎无学习成本
适用场景 微服务内部通信、高性能场景 对外 API、浏览器交互

选型的决策框架:微服务内部通信(服务间调用)→ gRPC(性能、类型安全、流式支持的价值最大化);对外 API(面向第三方或浏览器)→ REST(通用性、可调试性、无需额外代理);混合策略——内部用 gRPC、对外暴露 REST(通过 gRPC-Gateway 自动生成 REST 端点),内外兼修,各取所长。

gRPC 的拦截器:认证、日志与链路追踪

gRPC 的拦截器类似 Web 框架的中间件——在 RPC 调用的前后插入自定义逻辑。Unary 拦截器:客户端拦截器在发送请求前插入认证头;服务端拦截器在处理请求前验证认证。Stream 拦截器:对流式调用的每条消息进行拦截。常见的拦截器用例:认证——验证 JWT Token 或 API Key;日志——记录请求方法、耗时、状态码;链路追踪——从上游透传 traceId 或生成新的 traceId;限流——在拦截器层实现令牌桶限流。拦截器的顺序:多个拦截器按注册顺序依次执行(洋葱模型——请求按注册顺序穿过拦截器,响应按相反顺序返回)。拦截器是 gRPC 的横切关注点的统一入口。

gRPC 的超时与取消:deadline 传播机制

gRPC 内建了超时与取消的支持——每个 RPC 调用都可以设置 deadline(截止时间),并且 deadline 会沿着调用链传播。deadline 传播的机制:客户端设置 deadline(如 5 秒),gRPC 自动将剩余时间通过 HTTP/2 头(grpc-timeout 头)传递给服务端——服务端检查剩余时间,如果已不足以下游调用的最低要求,直接返回 DEADLINE_EXCEEDED(不再发起下游调用)。deadline 传播的价值:避免了「上游已超时但下游还在继续处理」的浪费——如果整个调用链的超时预算是 5 秒,上游已消耗 4.5 秒,下游只有 0.5 秒的预算——如果下游的操作需要 2 秒,直接返回超时比执行了 2 秒后被丢弃更有效率。取消机制:客户端取消调用后,gRPC 框架会通知服务端取消处理(通过 HTTP/2 的 RST_STREAM 帧)——服务端可以监听取消信号并中止处理(释放资源、停止计算)。deadline 传播与取消机制的结合,构建了端到端的资源管理——不让已经超时的请求继续消耗下游的资源。

gRPC 的拦截器:认证日志与链路追踪

gRPC 的拦截器类似 Web 框架的中间件在 RPC 调用的前后插入自定义逻辑。Unary 拦截器:客户端拦截器在发送请求前插入认证头服务端拦截器在处理请求前验证认证。Stream 拦截器:对流式调用的每条消息进行拦截。常见的拦截器用例:认证验证 JWT Token 或 API Key、日志记录请求方法耗时状态码、链路追踪从上游透传 traceId、限流在拦截器层实现令牌桶限流。拦截器的顺序:多个拦截器按注册顺序依次执行洋葱模型。拦截器是 gRPC 的横切关注点的统一入口。

gRPC vs REST 的选型决策

gRPC 与 REST 的选型取决于通信场景。微服务内部通信选 gRPC(性能、类型安全、流式支持的价值最大化);对外 API 面向第三方或浏览器选 REST(通用性、可调试性、无需额外代理)。混合策略:内部用 gRPC 对外暴露 REST 通过 gRPC-Gateway 自动生成 REST 端点——内外兼修各取所长。gRPC-Web 的补充:浏览器直接调 gRPC 需要 gRPC-Web 代理——这是 gRPC 在浏览器场景的主要短板但 gRPC-Gateway 可以桥接。

gRPC 的四种通信模式

gRPC 支持四种通信模式覆盖不同的交互场景。Unary 一元调用:客户端发一个请求服务端返一个响应——与传统 HTTP 相同最常用。Server Streaming 服务端流:客户端发一个请求服务端返回一串消息——适用场景:LLM 的 SSE 流式输出、大文件分块下载、实时推送。Client Streaming 客户端流:客户端发送一串消息服务端返回一个响应——适用场景:批量上传、传感器数据推送。Bidirectional Streaming 双向流:客户端与服务端同时收发消息流——适用场景:实时聊天、协作编辑、游戏状态同步。四种模式的选择取决于交互的对称性与数据量。

gRPC 的安全性与认证

gRPC 的安全性比 REST 更复杂也更强。TLS 加密:gRPC 支持 TLS 与 mTLS(双向 TLS——客户端也提供证书,服务端验证客户端身份——服务间通信的零信任安全基础)。认证方式:Token 认证在 metadata 中携带认证信息,服务端拦截器验证 Token。gRPC 的授权:基于方法的授权(允许服务 A 调用方法 X 但不允许方法 Y——通过拦截器检查方法名与 Token 的 scope)。gRPC-Web 的安全差异:浏览器通过 gRPC-Web 代理访问 gRPC 服务——代理层需要额外的安全考虑。

gRPC 的生态工具链

gRPC 的生态工具链包括多个提升开发效率的工具。grpcurl 是 gRPC 的 curl 通过反射或 proto 文件直接调用 gRPC 方法调试的必备工具。grpcui 是 gRPC 的 Web UI 基于 grpcurl 的交互式界面可以在浏览器中测试 gRPC 方法。ghz 是 gRPC 的压力测试工具支持多种负载模式与指标输出。grpc-gateway 将 gRPC 服务自动暴露为 REST API 通过 proto 注解生成反向代理一个服务同时提供 gRPC 与 REST 接口。这些工具构成了 gRPC 的开发调试测试工具链——好工具是技术选型的重要加分项 gRPC 的工具链已经成熟到可以与 REST 生态媲美。

gRPC 的安全性:mTLS 与认证授权

gRPC 的安全性比 REST 更复杂也更强。TLS 加密 gRPC 支持 TLS 与 mTLS 双向 TLS——客户端也提供证书服务端验证客户端身份——服务间通信的零信任安全基础。认证方式 Token 认证在 metadata 中携带认证信息服务端拦截器验证 Token。gRPC 的授权基于方法的授权通过拦截器检查方法名与 Token 的 scope。gRPC-Web 的安全差异浏览器通过 gRPC-Web 代理访问 gRPC 服务——代理层需要额外的安全考虑。

gRPC 的负载均衡与重试策略

gRPC 的负载均衡有多种实现层级。客户端负载均衡:gRPC 内建的负载均衡策略(pick_first 或 round_robin),客户端从服务发现获取地址列表自行选择。代理负载均衡:通过 L7 代理(如 Envoy)转发 gRPC 请求——代理可以理解 HTTP/2 帧做更精细的路由。gRPC 的重试策略:在服务配置中定义(Service Config),支持对特定方法配置重试次数与重试条件(仅对状态码为 UNAVAILABLE 的调用重试),重试的退避策略(指数退避加抖动)。gRPC 的重试预算机制:限制重试占总请求的比例(如不超过 10%),防止重试风暴放大故障。

小结

gRPC 收成四条:技术底座是 HTTP/2 + Protobuf——多路复用消除连接数限制、二进制序列化提高效率、强类型接口保证前后端一致;四种通信模式覆盖不同交互场景——Unary(请求-响应)、Server/Client Streaming(单向流)、Bidirectional(双向流);gRPC vs REST 不是替代关系——内部用 gRPC 提性能、对外用 REST 保通用,gRPC-Gateway 做桥接;浏览器需要 gRPC-Web 代理——这是 gRPC 在浏览器场景的主要短板。gRPC 的选型一句话:服务间通信选 gRPC(性能与类型安全),面向用户选 REST(通用与可调试)——内外分工,各取所长。

参考资料

  • gRPC 官方文档 —— 协议规范与多语言实现
  • HTTP/2 RFC 7540 —— 多路复用与二进制分帧的协议规范
  • 本库前篇:《SSE 流式输出实战》《Tcp/Ip 协议精解》
← 返回资讯列表

读者留言

COMMENTS 暂无
仅本站原创文章开放留言 · 请勿留下手机号、邮箱等个人信息

还没有留言,来说第一句?