说说 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/

面试考察点

  1. 基础概念掌握度:面试官不仅仅是想知道 HTTP 和 RPC 的字面区别,更是想知道你是否理解它们在分布式系统中的定位——HTTP 是应用层协议,而 RPC 是一种通信范式,二者并不完全在同一层级上对比。

  2. 架构设计意识:考察你在微服务架构中,能否根据实际场景选择合适的通信方式,而不是盲目跟风。

  3. 技术深度与广度:能否从协议层、序列化、服务治理等多个维度进行对比分析,而不仅仅是 "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 MethodIDL(接口定义语言)或接口契约
跨语言天然跨语言依赖框架,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,兼具性能与跨语言
企业内部多语言微服务gRPCIDL 定义接口,天然支持多语言

核心原则对外用 HTTP,对内用 RPC

面试高频追问

  1. 追问一:gRPC 和 Dubbo 有什么区别?

    • gRPC 基于 HTTP/2 + Protobuf,天然跨语言,由 Google 开源;Dubbo 主要面向 Java 生态,自定义 TCP 协议,服务治理能力更丰富。两者可以结合使用(Dubbo 3.x 已支持 gRPC 协议)。
  2. 追问二:RPC 框架是怎么做到 "像调用本地方法一样" 的?

    • 核心是 动态代理。消费者端通过 JDK 动态代理或字节码增强生成接口的代理对象,调用方法时,代理对象将方法名、参数类型、参数值序列化后通过网络发送给提供者,提供者反序列化后执行真实方法,再将结果序列化返回。
  3. 追问三:既然 RPC 性能更好,为什么不全部用 RPC?

    • RPC 需要引入 SDK 依赖,耦合度高;HTTP 是标准化协议,任何语言、任何平台都能直接调用。对外暴露的服务如果用 RPC,相当于强制调用方引入你的技术栈,这不现实。

常见面试变体

  • 变体一:"为什么微服务内部通信用 RPC 而不是 HTTP?"
  • 变体二:"Dubbo 和 Spring Cloud 有什么区别?"
  • 变体三:"gRPC 为什么性能比 HTTP REST 好?"
  • 变体四:"介绍一下 RPC 的调用流程。"

记忆口诀

HTTP 通用开放,RPC 高效内聚:对外用 HTTP(谁都能调),对内用 RPC(快且治理强)。记住 RPC 的核心是 "像调本地方法一样调远程方法",靠的是 动态代理 + 序列化 + 网络传输

总结

HTTP 是标准化协议,适合对外开放和跨系统通信;RPC 是高效的通信范式,适合微服务内部调用。两者不是替代关系,而是互补关系。实际架构中,对外 HTTP、对内 RPC 是最常见的最佳实践。选择的关键在于:是否需要跨语言、是否需要高性能、是否需要内置服务治理。