1. gRPC 概述
gRPC 是 Google 开源的高性能远程过程调用(RPC)框架,基于 HTTP/2 协议传输,使用 Protocol Buffers(protobuf)作为接口定义语言(IDL)和序列化工具。它允许客户端应用像调用本地方法一样直接调用另一台机器上的服务端方法,屏蔽了网络通信、序列化、反序列化等底层细节。
核心定位:gRPC 不是简单的 HTTP API 封装,而是一套完整的契约驱动型通信体系——服务接口、消息结构、错误码、流式语义全部在 .proto 文件中定义,代码生成器自动产出客户端和服务端骨架。
1.1 gRPC 与 REST 对比
| 对比维度 | gRPC | REST |
|---|---|---|
| 协议 | HTTP/2(多路复用、头部压缩) | HTTP/1.1 或 HTTP/2 |
| 数据格式 | Protocol Buffers(二进制,紧凑高效) | JSON / XML(文本,冗余大) |
| 接口定义 | .proto 文件(强类型契约) | OpenAPI / Swagger(文档驱动) |
| 流式通信 | 原生支持:单向流、双向流 | 需额外实现 SSE / WebSocket |
| 代码生成 | 内置 protoc 编译器,多语言一键生成 | 需第三方工具(如 swagger-codegen) |
| 浏览器支持 | 需 gRPC-Web 代理 | 原生支持 |
| 适用场景 | 微服务间通信、实时流、IoT | Web API、公开接口、资源型 CRUD |
关键差异:REST 面向资源(Resource),以 HTTP 动词操作资源;gRPC 面向服务(Service),以方法调用定义业务逻辑。gRPC 在性能、类型安全、流式处理上明显优于 REST,但浏览器兼容性较弱。
1.2 gRPC 核心优势
- 高性能:基于 HTTP/2 多路复用,单个连接可并行处理多个请求;Protocol Buffers 二进制序列化比 JSON 小 3~10 倍,解析速度快 20~100 倍。
- 双向流:支持四种通信模式——一元(Unary)、服务端流、客户端流、双向流,满足实时推送、大数据分块、聊天等场景。
- 多语言互操作:官方支持 Go、Java、Python、C++、Ruby、Node.js 等 11+ 语言,.proto 文件作为单一真相源,跨语言调用无需额外适配。
- 契约驱动:接口和消息结构在 .proto 中严格定义,编译期即可发现类型错误,避免运行时协议不匹配问题。
- 内置认证与负载均衡:支持 SSL/TLS 加密、Token 认证、拦截器扩展;与 Kubernetes、Envoy 等基础设施深度集成。
1.3 gRPC 应用场景
| 场景 | 说明 | 典型示例 |
|---|---|---|
| 微服务间通信 | 低延迟、高吞吐的内部服务调用 | 订单服务调用库存服务 |
| 实时数据流 | 服务端推送或双向持续传输 | 股票行情推送、日志收集 |
| IoT 设备通信 | 二进制协议节省带宽,适合弱网环境 | 传感器数据上报、远程指令下发 |
| 多语言异构系统 | 不同技术栈团队通过 .proto 统一契约 | Go 后端 + Python 数据服务 + Java 网关 |
| 移动端与后端 | 通过 gRPC-Web 或原生 gRPC 减少请求体积 | App 用户登录、消息同步 |
注意:gRPC 不适合浏览器直接调用(需 gRPC-Web 代理),也不适合对外暴露的公共 RESTful API。对于需要广泛浏览器兼容性的场景,建议使用 REST 或 GraphQL。
1.4 gRPC 通信模式
gRPC 基于 HTTP/2 流(Stream)定义了四种 RPC 类型,覆盖从简单请求-响应到复杂双向流的所有通信需求:
- 一元 RPC(Unary):客户端发送一个请求,服务端返回一个响应,类似传统 HTTP 调用。
- 服务端流 RPC(Server Streaming):客户端发送一个请求,服务端返回一个消息流,适用于批量数据推送。
- 客户端流 RPC(Client Streaming):客户端发送一个消息流,服务端返回一个响应,适用于大数据上传或批量提交。
- 双向流 RPC(Bidirectional Streaming):双方独立发送消息流,适用于实时聊天、协同编辑等场景。
Go 实现要点:在 Go 中,gRPC 流通过
grpc.ServerStream 和 grpc.ClientStream 接口管理。服务端流使用 stream.Send() 逐条推送;客户端流使用 stream.Recv() 循环读取;双向流则同时调用 Send() 和 Recv() 在两个 goroutine 中独立处理。