MD 更新:2026/5/29

gRPC

[!abstract] 一句话定义 gRPC 是 Google 开源的远程过程调用框架——用 .proto 文件定义服务接口,用 Protobuf 二进制协议序列化,跑在 HTTP/2 上,自动生成多语言客户端代码。它是微服务间”对话”的高速公路。

为什么需要它?

假设你有一个电商系统,订单服务需要调用库存服务扣减库存。用 REST + JSON 的话,你需要:手写 HTTP 客户端、拼 URL、序列化/解析 JSON(体积大、慢)、自己处理超时和重试、跨语言时还得重新写一遍客户端。服务多了以后,这些胶水代码变成噩梦——接口变了没人知道,类型错误运行时才发现,性能被 JSON 拖慢。

gRPC 的解法:一份 .proto 文件 = 接口文档 + 类型系统 + 代码生成器。定义一次,各语言自动生成类型安全的客户端;Protobuf 二进制编码比 JSON 小 3-10 倍、快 20-100 倍;HTTP/2 多路复用让连接不再成为瓶颈。

核心直觉

把 gRPC 想象成一个国际翻译团队

  • .proto 文件是团队的”通用词汇表”——所有人(Go、Java、Python 团队)都按这个词汇表说话,不会鸡同鸭讲
  • Protobuf 编码是”速记 shorthand”——比写完整句子(JSON)快得多、短得多,但只有懂速记的人(protoc 编译器生成的代码)能读懂
  • HTTP/2是”同一条电话线上的多路通话”——不需要为每个对话重新拨号(建立 TCP 连接),多对对话可以同时进行

核心价值就一句话:把”服务之间怎么对话”这件事标准化、自动化、高性能化

它是怎么工作的?

gRPC 的工作流程可以拆成三个阶段:定义 → 生成 → 调用

流程图

flowchart LR
    A[".proto 文件<br/>定义服务契约"] -->|"protoc 编译器"| B["生成代码<br/>Server + Client Stub"]
    B --> C["服务端实现接口"]
    B --> D["客户端调用远程方法"]
    C -->|"HTTP/2 + Protobuf"| D

    style A fill:#e1f5fe
    style B fill:#fff3e0
    style C fill:#e8f5e9
    style D fill:#fce4ec

请求-响应时序

sequenceDiagram
    participant Client as 客户端 (Go)
    participant Channel as gRPC Channel
    participant Server as 服务端 (Java)

    Client->>Channel: 调用 GetUser(userId)
    Note over Channel: 序列化为 Protobuf 二进制
    Channel->>Server: HTTP/2 POST /user.UserService/GetUser
    Note over Server: 反序列化 → 执行业务逻辑
    Server-->>Channel: Protobuf 响应帧
    Note over Channel: 反序列化为 Go 对象
    Channel-->>Client: 返回 User 对象

关键步骤详解

第一步:定义契约(.proto

syntax = "proto3";

service UserService {
  rpc GetUser(GetUserRequest) returns (User);
  rpc ListUsers(ListUsersRequest) returns (stream User);  // 服务端流
}

message GetUserRequest {
  string user_id = 1;  // 字段编号 = 二进制中的标签
}

message User {
  string id = 1;
  string name = 2;
  string email = 3;
}

第二步:生成代码

protoc --go_out=. --go-grpc_out=. user.proto
# 生成:user.pb.go(消息类型)+ user_grpc.pb.go(服务接口)

第三步:实现与调用

// 服务端:实现接口
type server struct{ pb.UnimplementedUserServiceServer }
func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.User, error) {
    return &pb.User{Id: req.UserId, Name: "Alice"}, nil
}

// 客户端:像调用本地函数一样
user, err := client.GetUser(ctx, &pb.GetUserRequest{UserId: "123"})

关键组件 / 核心要素

组件作用类比
.proto 文件定义服务接口、消息结构、字段编号建筑蓝图
Protobuf 编码将消息序列化为紧凑的二进制格式摩尔斯电码(比文字更短)
protoc 编译器读取 .proto,生成各语言的序列化/客户端代码自动施工队
gRPC Channel客户端与服务端之间的持久连接,管理负载均衡和连接池电话总机
拦截器(Interceptor)在请求/响应前后插入通用逻辑(日志、认证、追踪)快递安检站
Deadline / 超时请求级别的超时控制,自动传播到下游调用快递的”送达时限”

四种通信模式

模式请求响应适用场景
一元(Unary)11CRUD、查询——最常用
服务端流1N实时推送、日志流
客户端流N1文件上传、批量写入
双向流NN聊天、实时协作

与相关概念的关系

[!info] vs GraphQL gRPC 是服务间的高速公路——追求性能和类型安全,像打电话一样直接高效。GraphQL 是客户端到服务端的自助餐——前端按需取数据,灵活但多一层解析开销。架构中常常两者共存:对外 GraphQL,对内 gRPC。

[!note] 依赖于 HTTP/2 gRPC 的多路复用、双向流、头部压缩都建立在 HTTP/2 之上。没有 HTTP/2,gRPC 就失去了性能优势的根基。这也意味着:客户端必须支持 HTTP/2(浏览器原生不支持,需要 gRPC-Web 代理)。

[!tip] 被 微服务架构 广泛使用 gRPC 是微服务通信的事实标准之一。Kubernetes 生态中,Istio/Envoy 原生支持 gRPC 负载均衡;etcd、CoreDNS 等基础设施组件本身也用 gRPC 通信。

[!info] vs REST API REST 是”写信”——人类可读、浏览器原生、生态成熟。gRPC 是”打电话”——二进制高效、类型安全、但需要双方都懂”语言”(生成的客户端代码)。公开 API 用 REST,内部服务间用 gRPC,是当前最常见的组合。

典型应用场景

  • 微服务内部通信 — 服务间高频调用,低延迟高吞吐(电商的订单→库存→支付链路)
  • 流式数据处理 — 实时日志收集、行情推送、IoT 设备数据上报(利用双向流模式)
  • 多语言异构系统 — Go/Java/Python 团队各写各的服务,.proto 保证接口一致
  • 移动客户端 — Protobuf 体积小,节省移动端带宽和电量
  • ML 推理服务 — TensorFlow Serving、Triton Inference Server 都提供 gRPC 接口

常见误解与陷阱

[!danger] ❌ 误以为:gRPC 比 REST “更快”所以应该全面替换 ✅ 实际上:gRPC 的性能优势在高频内部通信中才显著。对于低频公开 API,REST 的调试便利性、浏览器兼容性、生态工具链优势更大。选型要看场景,不是”越快越好”。

[!danger] ❌ 误以为:Protobuf 比 JSON 更好 ✅ 实际上:Protobuf 是二进制不可读的——你无法用 curl 直接调试,需要专门工具(如 grpcurlgrpc-web-devtools)。这是用性能换可读性的取舍。

[!danger] ❌ 误以为:gRPC 只能在 Google Cloud 用 ✅ 实际上:gRPC 是 CNCF 毕业项目,跨平台跨云。AWS、Azure、阿里云都原生支持。它是开源的,不绑定任何云厂商。

[!danger] ❌ 误以为:浏览器可以直接调用 gRPC ✅ 实际上:浏览器不支持 HTTP/2 的底层特性(如 Trailers),需要通过 gRPC-Web 代理层转换。这也是为什么面向浏览器的 API 通常还是用 REST 或 GraphQL。

延伸阅读

  • 想深入理解原理 → 阅读 gRPC 官方文档 的 “Core Concepts” 部分,理解 Channel、Stub、Service 的关系
  • 想看工程实践 → 研究 Kubernetes 生态中 etcd、Istio 如何使用 gRPC,以及 gRPC 的负载均衡和健康检查策略
  • 想了解前沿进展 → 关注 gRPC 的 Connect 协议(兼容 gRPC/REST/gRPC-Web),以及 gRPC 在 Serverless/Edge 场景的适配

前置知识HTTP/2 · Protocol Buffers 同族概念GraphQL · REST · Thrift · Dubbo 应用场景微服务架构 · 事件驱动架构 · 企业服务总线(ESB)