Chapter 01

gRPC 简介:RPC 原理与核心优势

从 RPC 本质出发,理解 gRPC 为什么比 REST 更适合微服务间通信,掌握 HTTP/2 基础与工具链安装

什么是 RPC

RPC(Remote Procedure Call,远程过程调用)是一种通信协议,让程序可以像调用本地函数一样调用远程机器上的函数,而无需关心底层网络传输细节。

当你调用 userService.GetUser(ctx, &GetUserRequest{Id: 123}) 时,这行代码在网络上传输,由另一台服务器上的 Go 程序执行,返回结果给你——这就是 RPC 的魔法。

RPC vs REST:设计哲学的根本差异

REST API
# 资源导向(名词 + 动词)
GET    /users/123
POST   /users
PUT    /users/123
DELETE /users/123

# 数据格式:JSON(文本)
{
  "id": 123,
  "name": "Alice",
  "email": "alice@example.com"
}
gRPC
// 过程导向(动词)
rpc GetUser(GetUserRequest)
    returns (UserResponse)

rpc CreateUser(CreateUserRequest)
    returns (UserResponse)

// 数据格式:Protobuf(二进制)
// 比 JSON 体积小 3-10 倍
对比维度RESTgRPC
协议HTTP/1.1(通常)HTTP/2(必须)
序列化JSON(文本)Protobuf(二进制)
接口定义OpenAPI/Swagger(可选).proto 文件(必须)
类型安全弱(运行时校验)强(编译时校验)
流式传输SSE/WebSocket(额外)原生四种流式模式
代码生成可选内置,多语言
浏览器支持直接支持需要代理(grpc-web)
可读性高(JSON 人类可读)低(二进制需工具)
适用场景公开 API、BFF、移动端微服务内部通信

HTTP/2 基础:gRPC 的传输基础

gRPC 强制要求 HTTP/2,这是它高性能的根本原因。理解 HTTP/2 的三大核心特性,就理解了 gRPC 为什么快。

多路复用(Multiplexing)

HTTP/1.1 的一个连接同一时刻只能处理一个请求(即使使用 Keep-Alive 也只能串行)。HTTP/2 将所有数据拆分为 帧(Frame),每个请求/响应是一个 流(Stream),多个流可以在同一个 TCP 连接上并发传输——彻底解决了队头阻塞(Head-of-Line Blocking)问题。

HTTP/1.1(6 个请求需要多个连接):
连接1: [请求A] ─── [响应A]
连接2: [请求B] ─── [响应B]
连接3: [请求C] ─── [响应C]

HTTP/2(6 个请求复用 1 个连接):
连接1: [帧A1][帧B1][帧C1][帧A2][帧C2][帧B2]...
       ↑交错发送,互不阻塞

头部压缩(HPACK)

HTTP/1.1 每次请求都要发送完整的 HTTP 头(如 Cookie、User-Agent 等),往往比实际数据还大。HTTP/2 使用 HPACK 算法压缩头部,对于重复的头字段只发送差量,节省大量带宽。

服务端推送(Server Push)

服务端可以在客户端请求之前主动推送资源(gRPC 的流式模式即基于此)。这使得 gRPC 的服务端流、双向流得以实现。

gRPC 的四大核心优势

四种通信模式概览

// 1. Unary RPC(一问一答,最常用)
rpc GetUser(GetUserRequest) returns (UserResponse);

// 2. 服务端流(服务端推送多条消息)
rpc ListUsers(ListRequest) returns (stream UserResponse);

// 3. 客户端流(客户端发多条,服务端一次响应)
rpc UploadChunks(stream Chunk) returns (UploadResult);

// 4. 双向流(全双工,实时通信)
rpc Chat(stream Message) returns (stream Message);

适用场景

场景推荐程度理由
微服务内部通信强烈推荐性能最优,类型安全,多语言支持
IoT 设备与云端推荐二进制协议节省带宽,适合弱网环境
移动端后端(BFF)推荐减少数据传输量,降低移动端电量消耗
实时数据推送推荐流式模式天然适合实时场景
公开 API不推荐浏览器不直接支持,调试不便
需要 CDN 缓存不推荐POST 请求 + 二进制,CDN 无法缓存

安装工具链

安装 protoc 编译器

# macOS(Homebrew)
brew install protobuf
protoc --version  # libprotoc 27.x

# Linux(Ubuntu)
sudo apt install -y protobuf-compiler

# 或从 GitHub Releases 下载二进制
# https://github.com/protocolbuffers/protobuf/releases
PB_REL="https://github.com/protocolbuffers/protobuf/releases"
curl -LO $PB_REL/download/v27.0/protoc-27.0-linux-x86_64.zip
unzip protoc-27.0-linux-x86_64.zip -d $HOME/.local
export PATH="$HOME/.local/bin:$PATH"

安装 Go 插件

# 安装 protoc-gen-go(生成消息结构体)
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest

# 安装 protoc-gen-go-grpc(生成 gRPC 服务代码)
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

# 确保 $GOPATH/bin 在 PATH 中
export PATH="$PATH:$(go env GOPATH)/bin"

# 验证
protoc-gen-go --version      # protoc-gen-go v1.34.x
protoc-gen-go-grpc --version # protoc-gen-go-grpc 1.4.x

安装 Python 插件

# 创建虚拟环境(推荐)
python3 -m venv venv
source venv/bin/activate

# 安装 grpcio 运行时 + 代码生成工具
pip install grpcio grpcio-tools

# 验证
python3 -m grpc_tools.protoc --version

安装 buf(现代工具链推荐)

# macOS / Linux
brew install bufbuild/buf/buf

# 或直接下载
curl -sSL \
  "https://github.com/bufbuild/buf/releases/latest/download/buf-$(uname -s)-$(uname -m)" \
  -o /usr/local/bin/buf
chmod +x /usr/local/bin/buf

buf --version  # 1.x.x

buf vs protoc:buf 是 protoc 的现代替代品,提供统一配置文件(buf.yaml)、lint 检查、breaking change 检测、BSR(Buf Schema Registry)远程依赖管理。新项目推荐使用 buf;遗留项目可以先用 protoc 熟悉流程。

名词解释

本章小结:gRPC 通过 HTTP/2 + Protobuf 实现了高性能、强类型、多语言的远程调用。它不是 REST 的替代品,而是微服务内部通信的最佳选择。下一章我们深入 Protobuf 语法,掌握定义数据结构的核心技能。