第01章:什么是 RPC —— 从零理解远程过程调用
本章目标
学完本章后,你将能够:
- 用自己的话解释 RPC 是什么
- 说出 RPC 和 REST 的至少 5 个区别
- 理解 RPC 三要素(服务定义、序列化、传输协议)
- 了解主流 RPC 框架的差异
前置知识
- 了解 HTTP 协议基础(你已学过 Gin 教程的 HTTP 章节)
- 无需 RPC 基础
1.1 什么是 RPC
**RPC(Remote Procedure Call,远程过程调用)**让你像调用本地函数一样调用远程服务器上的函数。
本地函数调用:
result := Add(1, 2) // 直接调用,结果立即可得
RPC 远程调用:
result := client.Add(ctx, &AddRequest{A: 1, B: 2}) // 看起来像本地调用
// 实际上:参数序列化 → 网络传输 → 远程执行 → 结果序列化 → 返回一句话理解
RPC = "让远程服务上的函数,看起来像本地函数一样调用"
就像你打电话给朋友帮你查资料:
- 你(Client):打电话说"帮我查一下张三的年龄"
- 朋友(Server):查到了,回复"25岁"
- 你不需要知道朋友怎么查的,只需要知道问什么、回答什么1.2 进程间通信演进
阶段1:单体应用
┌─────────────────────┐
│ 所有代码在一个进程里 │
│ 函数调用 = 内存跳转 │
└─────────────────────┘
阶段2:Socket 通信
┌────────┐ TCP/UDP ┌────────┐
│ 进程A │<─────────>│ 进程B │
└────────┘ 原始字节 └────────┘
阶段3:HTTP/REST API
┌────────┐ HTTP ┌────────┐
│ 进程A │<─────────>│ 进程B │
└────────┘ JSON/XML └────────┘
阶段4:RPC
┌────────┐ 基于HTTP/2 ┌────────┐
│ 进程A │<───────────>│ 进程B │
└────────┘ Protobuf └────────┘
调用远程函数就像调用本地函数1.3 RPC vs REST
| 维度 | REST | gRPC |
|---|---|---|
| 设计哲学 | 面向资源(URL+HTTP方法) | 面向服务(函数调用) |
| 数据格式 | JSON/XML(文本) | Protobuf(二进制) |
| 协议 | HTTP/1.1 | HTTP/2 |
| Schema | 无强制(OpenAPI可选) | .proto 文件强制定义 |
| 代码生成 | 手动/第三方 | 官方 protoc 自动生成 |
| 性能 | 一般(JSON序列化慢、文本大) | 高(Protobuf快5-10倍、小3-5倍) |
| 流式通信 | WebSocket/SSE(额外技术) | 原生支持(服务端流/客户端流/双向流) |
| 浏览器支持 | ✅ 原生支持 | ❌ 需要 gRPC-Web |
| 可读性 | ✅ JSON 肉眼可读 | ❌ Protobuf 二进制不可读 |
| 学习成本 | 低 | 中高(proto语法 + 工具链) |
| 适用场景 | 对外 API、浏览器调用 | 微服务间通信、移动端 |
什么时候用 RPC,什么时候用 REST?
微服务之间通信 → gRPC(高性能 + 强类型 + 流式)
对外开放 API → REST(浏览器友好 + 调试方便)
移动 App → gRPC(省流量 + 快)
文件上传/下载 → gRPC 流式(边传边处理)
简单 CRUD → REST(简单够用)1.4 RPC 核心三要素
┌────────────────────────────────────────────┐
│ RPC 框架 │
│ │
│ 1. 服务定义(IDL) │
│ .proto 文件定义有哪些方法、什么参数 │
│ │
│ 2. 序列化(Serialization) │
│ Protobuf:Go struct ↔ 二进制 bytes │
│ │
│ 3. 传输协议(Transport) │
│ HTTP/2:多路复用、流式、头部压缩 │
└────────────────────────────────────────────┘1.5 主流 RPC 框架对比
| 框架 | 开发者 | 协议 | IDL | 特点 |
|---|---|---|---|---|
| gRPC | HTTP/2 | Protobuf | ⭐ 最流行,多语言,流式 | |
| Thrift | 自定义 | Thrift IDL | 多语言,协议灵活 | |
| Dubbo | 阿里 | 自定义 | Java Interface | Java 生态 |
| tRPC | 腾讯 | 自定义 | Protobuf | 腾讯内部广泛使用 |
1.6 gRPC 的四大优势
| 优势 | 说明 |
|---|---|
| 高性能 | Protobuf 二进制序列化 + HTTP/2 多路复用 |
| 多语言 | 官方支持 Go/Java/C++/Python/Node.js/Ruby/PHP 等 10+ 语言 |
| 流式通信 | 原生支持服务端流、客户端流、双向流 |
| 生态丰富 | 拦截器、负载均衡、健康检查、Gateway、丰富的工具链 |
常见错误
错误1:以为 RPC 就是 gRPC
RPC 是一种思想/范式,gRPC 是 Google 对这个思想的具体实现。还有 Thrift、Dubbo 等其他实现。
错误2:以为 gRPC 替代了 REST
不是替代,是互补。浏览器直接调 gRPC 比较麻烦(需要 gRPC-Web),对外 API 还是 REST 更方便。微服务之间用 gRPC,对外暴露 REST。
错误3:以为 Protobuf 比 JSON 只是"快一点"
其实是数量级的差距:序列化快 5-10 倍,数据量小 3-5 倍。在微服务高并发场景下,差距巨大。
本章小结
- RPC = 像调本地函数一样调远程函数
- RPC vs REST:面向函数 vs 面向资源、Protobuf vs JSON、HTTP/2 vs HTTP/1.1
- RPC 三要素:IDL定义 + 序列化 + 传输协议
- gRPC 四大优势:性能、多语言、流式、生态
练习题
- 用自己的话解释 RPC 的三个核心要素。
- 画出 RPC 请求的完整流程图(Client → Stub → 网络 → Server → 返回)。
- 列举 gRPC 和 REST 至少 5 个区别。
- 什么场景用 gRPC,什么场景用 REST?各举两个例子。
- (思考题)为什么 gRPC 用 Protobuf 而不用 JSON?Protobuf 的二进制格式比 JSON 文本格式到底快在哪里?