说说 HTTP 和 RPC 的区别是什么?
一则或许对你有用的小广告
欢迎 加入小哈的星球 ,你将获得: 专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目: 《Spring AI 项目实战(问答机器人、RAG 增强检索、联网搜索)》 正在持续爆肝中,基于
Spring AI + Spring Boot3.x + JDK 21..., 点击查看; - 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot3.x + JDK 17..., 点击查看项目介绍; 演示链接: http://116.62.199.48:7070/; - 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/
面试考察点
-
基础概念掌握度:面试官不仅仅是想知道 HTTP 和 RPC 的字面区别,更是想知道你是否理解它们在分布式系统中的定位——HTTP 是应用层协议,而 RPC 是一种通信范式,二者并不完全在同一层级上对比。
-
架构设计意识:考察你在微服务架构中,能否根据实际场景选择合适的通信方式,而不是盲目跟风。
-
技术深度与广度:能否从协议层、序列化、服务治理等多个维度进行对比分析,而不仅仅是 "HTTP 用 JSON、RPC 用二进制" 这种表面的理解。
核心答案
HTTP 和 RPC 不是同一层级的东西:HTTP 是一种应用层协议,而 RPC 是一种远程调用的架构思想。RPC 可以基于 HTTP 协议实现,也可以基于自定义的 TCP 协议实现。
不过在实际开发中,我们通常拿 "HTTP RESTful API" 和 "RPC 框架(如 Dubbo、gRPC)" 来做对比,核心区别如下:
| 对比维度 | HTTP(RESTful) | RPC(Dubbo / gRPC) |
|---|---|---|
| 定位 | 通用应用层协议 | 远程过程调用框架 |
| 协议层级 | 基于 HTTP/1.1、HTTP/2 | 可自定义 TCP 协议,也可基于 HTTP/2 |
| 传输效率 | HTTP/1.1 头部较大,效率较低 | 自定义协议更精简,效率更高 |
| 序列化 | JSON / XML(可读性强) | Protobuf / Hessian / Kryo(二进制,更高效) |
| 服务治理 | 需借助外部组件(Nginx、Gateway) | 内置注册发现、负载均衡、熔断降级 |
| 接口定义 | URL + HTTP Method | IDL(接口定义语言)或接口契约 |
| 跨语言 | 天然跨语言 | 依赖框架,gRPC 天然跨语言,Dubbo 主要 Java |
| 调用方式 | 需手动构造请求 | 像调用本地方法一样透明 |
| 典型场景 | 对外开放 API、前后端通信 | 微服务内部通信 |
一句话总结:对外用 HTTP,对内用 RPC,两者不是互斥关系,而是互补关系。
深度解析
一、本质区别:协议 vs 思想
先理清一个关键概念——HTTP 是协议,RPC 是思想。
上图展示了 RPC 与 HTTP 的关系。关键要点:
- RPC 是一种通信范式:目标是让远程调用像本地调用一样简单,开发者不需要关心网络细节。
- HTTP 是一种具体的协议:定义了请求/响应的格式、状态码、头部等信息。
- 二者可以结合:gRPC 基于 HTTP/2 实现,Spring Cloud Feign 也基于 HTTP。所以 "HTTP vs RPC" 这个说法本身不够严谨,更准确的说法是 "RESTful HTTP API vs RPC 框架"。
二、调用体验对比
RPC 最大的优势就是——调用远程方法就像调用本地方法一样。
HTTP 调用方式(以 RestTemplate 为例):
// 需要手动构造 URL、处理响应
RestTemplate restTemplate = new RestTemplate();
String url = "http://user-service/api/users/" + userId;
User user = restTemplate.getForObject(url, User.class);
RPC 调用方式(以 Dubbo 为例):
// 像调用本地方法一样,完全透明
@DubboReference
private UserService userService;
public void doSomething() {
// 直接调用,框架帮你处理网络通信
User user = userService.getUserById(userId);
}
可以看到,RPC 框架屏蔽了网络通信的细节,开发者不需要关心 URL 拼接、序列化/反序列化等问题。
三、性能差异分析
性能差距主要来自两个方面:协议开销 和 序列化效率。
从报文对比可以看出关键差异:
- 协议开销:HTTP/1.1 每次请求都要携带大量头部信息(Host、Content-Type、User-Agent 等),而 RPC 自定义协议只保留必要的魔数、标志位和请求 ID,开销极小。
- 序列化效率:JSON 是文本格式,可读但冗长;Protobuf / Hessian 等二进制序列化体积更小、速度更快。同等数据下,Protobuf 的序列化体积通常只有 JSON 的 1/3 ~ 1/5。
四、服务治理能力对比
这是 RPC 框架在实际生产中最大的价值所在。
- HTTP 方案需要借助 Spring Cloud Gateway、Nacos、Sentinel 等多个组件组合实现服务治理,架构相对复杂。
- RPC 方案(如 Dubbo)将这些能力内置在框架中,开箱即用,开发者只需简单配置即可。
五、最佳实践:如何选择?
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 对外开放 API(第三方接入) | HTTP RESTful | 标准化、跨语言、易理解 |
| 前后端通信 | HTTP RESTful | 浏览器天然支持 HTTP |
| 微服务内部通信 | RPC(Dubbo / gRPC) | 高性能、内置服务治理 |
| 高并发低延迟场景 | gRPC | 基于 HTTP/2 + Protobuf,兼具性能与跨语言 |
| 企业内部多语言微服务 | gRPC | IDL 定义接口,天然支持多语言 |
核心原则:对外用 HTTP,对内用 RPC。
面试高频追问
-
追问一:gRPC 和 Dubbo 有什么区别?
- gRPC 基于 HTTP/2 + Protobuf,天然跨语言,由 Google 开源;Dubbo 主要面向 Java 生态,自定义 TCP 协议,服务治理能力更丰富。两者可以结合使用(Dubbo 3.x 已支持 gRPC 协议)。
-
追问二:RPC 框架是怎么做到 "像调用本地方法一样" 的?
- 核心是 动态代理。消费者端通过 JDK 动态代理或字节码增强生成接口的代理对象,调用方法时,代理对象将方法名、参数类型、参数值序列化后通过网络发送给提供者,提供者反序列化后执行真实方法,再将结果序列化返回。
-
追问三:既然 RPC 性能更好,为什么不全部用 RPC?
- RPC 需要引入 SDK 依赖,耦合度高;HTTP 是标准化协议,任何语言、任何平台都能直接调用。对外暴露的服务如果用 RPC,相当于强制调用方引入你的技术栈,这不现实。
常见面试变体
- 变体一:"为什么微服务内部通信用 RPC 而不是 HTTP?"
- 变体二:"Dubbo 和 Spring Cloud 有什么区别?"
- 变体三:"gRPC 为什么性能比 HTTP REST 好?"
- 变体四:"介绍一下 RPC 的调用流程。"
记忆口诀
HTTP 通用开放,RPC 高效内聚:对外用 HTTP(谁都能调),对内用 RPC(快且治理强)。记住 RPC 的核心是 "像调本地方法一样调远程方法",靠的是 动态代理 + 序列化 + 网络传输。
总结
HTTP 是标准化协议,适合对外开放和跨系统通信;RPC 是高效的通信范式,适合微服务内部调用。两者不是替代关系,而是互补关系。实际架构中,对外 HTTP、对内 RPC 是最常见的最佳实践。选择的关键在于:是否需要跨语言、是否需要高性能、是否需要内置服务治理。