为什么大厂内部微服务都用 RPC,而不用 HTTP/REST?

在微服务架构中,几十甚至上百个服务分散在不同的服务器上。它们之间必须频繁地交流:订单服务要找库存服务扣库存,用户服务要找积分服务加积分。
它们交流的“语言”主要有两种流派:REST (基于 HTTP) 和 RPC (远程过程调用)。
很多初学者会疑惑:“既然 HTTP 这么通用,为什么大厂内部(如阿里、字节、Google)的微服务全是 RPC(如 Dubbo, gRPC)?”
今天我们就来拆解这两者的本质区别。
💻 一、技术分析:通用性 vs 高性能
1. 选手介绍
-
REST (Representational State Transfer):
-
基于协议: HTTP/1.1 (通常)。
-
数据格式: JSON (文本)。
-
核心思想: “资源导向”。把一切看作资源,用 GET/POST/PUT/DELETE 动词来操作。
-
特点: 通用、解耦。浏览器、手机、服务器都能读懂。但报文臃肿(Header 很大),解析 JSON 慢。
-
RPC (Remote Procedure Call):
-
基于协议: TCP 或 HTTP/2 (gRPC)。
-
数据格式: 二进制 (Protobuf, Thrift, Hessian)。
-
核心思想: “动作导向”。就像调用本地函数一样调用远程服务。
-
特点: 极速、紧耦合。不需要发 HTTP 头,二进制传输极小,序列化极快。但需要双方约定好“接口定义”(IDL)。
2. 巅峰对决:为什么 RPC 更快?
| 维度 | REST (HTTP/JSON) | RPC (如 gRPC/Dubbo) |
|---|---|---|
| 通信协议 | HTTP/1.1(无状态,文本传输) | TCP 或 HTTP/2(长连接,二进制传输) |
| 报文大小 | 大。包含大量 Header、冗余的 JSON 字段名。 | 极小。二进制压缩,没有废话。 |
| 序列化 | JSON 序列化/反序列化(CPU 密集,慢)。 | Protobuf/Hessian(高效,快)。 |
| 开发体验 | 需关心 URL、Method、参数封装。 | 像调用本地 Java 方法一样简单:userService.getUser(id)。 |
| 适用场景 | 对外接口 (OpenAPI, 前端交互)。 | 内部微服务 (高并发,低延迟)。 |
🕵️ 二、故事场景:外交官 vs 特种兵
为了搞懂它们的区别,我们将 微服务通信 比作 “传递情报”。
1. REST (HTTP) —— “外交官的正式信函”
-
场景: 你(订单服务)要向陌生人(外部开发者/浏览器)请求数据。
-
沟通方式:
-
寒暄 (Headers): 信封上必须写满格式:“亲爱的服务器(Host),我是火狐(User-Agent),我要 JSON 格式(Content-Type)…”
-
正文 (JSON): 为了让谁都看懂,内容写得非常详尽。
-
{ "userName": "Bond", "age": 30 } -
传输: 哪怕只是发个数字“1”,也要包一个大大的信封。
-
评价: 礼貌、通用、谁都看得懂。但是废话太多,效率低,适合对外交流。
2. RPC (gRPC/Dubbo) —— “特种兵的暗号”
-
场景: 你(订单服务)要向你的队友(库存服务)请求数据。你们是自己人,讲究的是兵贵神速。
-
事前准备 (IDL):
-
你们出发前已经背熟了同一本密码本 (Proto文件/Interface)。约定好:第 1 个字节代表 ID,第 2 个字节代表数量。
-
沟通方式:
-
无寒暄: 甚至不需要打招呼,直接发信号。
-
正文 (Binary):
-
你只发送了一串二进制代码:
0A 04 42 6F 6E 64(对应 Bond)。 -
传输: 队友收到二进制,瞬间查密码本解码。
-
评价: 极速、高效、没有废话。但是只有拿了密码本(SDK)的自己人能听懂,不适合直接给浏览器看。
🎯 三、总结:内外有别,各司其职
在现代微服务架构中,通常是 “外 REST,内 RPC” 的混合模式。
- 对外暴露 (Gateway):
- 使用 REST (HTTP/JSON)。
- 原因: 浏览器和移动端对 HTTP 支持最好,防火墙友好,调试方便。
- 内部调用 (Backend):
- 使用 RPC (gRPC/Dubbo)。
- 原因: 内部成千上万次调用,哪怕每次节省 1 毫秒,累积起来就是巨大的性能提升和成本节省(省 CPU、省带宽)。
结论:如果你想让陌生人听懂,请用英语 (REST);如果你想让队友秒懂,请用暗号 (RPC)。
更多推荐
所有评论(0)