说说 HTTP 和 RPC 的区别是什么?
2026年01月09日
一则或许对你有用的小广告
欢迎 加入小哈的星球 ,你将获得: 专属的项目实战(已更新的所有项目都能学习) / 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 在通信模型、协议栈上的根本性差异。
- 序列化与性能的权衡:是否了解它们背后不同的序列化方式(如 JSON/XML vs Protobuf/Hessian)及其对性能、体积和开发效率的影响。
- 设计哲学与适用场景:能否理解它们不同的设计目标(通用 Web 标准 vs 高效内部服务通信),并据此分析各自的适用场景。
- 架构视野:在微服务或分布式系统架构的背景下,能否结合实际,阐述技术选型的思考,体现将理论知识应用于工程实践的能力。
核心答案
HTTP 和 RPC 的核心区别在于:HTTP 是一个通用的、无状态的、应用层的网络协议标准,而 RPC 是一种旨在实现像调用本地方法一样调用远程服务的框架或设计模式。
更直接地说:
- HTTP 是一种协议,定义了客户端与服务器之间通信的通用格式和规则(如 URL、Method、Header、Body),其设计初衷是为了万维网(Web)的超文本传输,现已广泛用于构建 RESTful API。
- RPC 是一种概念/框架,其核心目标是让开发者无感知地调用远程服务。为了实现这个目标,一个完整的 RPC 框架通常会自定义或封装底层通信协议(可能基于 TCP,也可能基于 HTTP),并集成高效的二进制序列化、服务发现、负载均衡、熔断降级等分布式服务治理能力。
简言之,你可以 “用 HTTP 协议来实现一种 RPC”(如 gRPC over HTTP/2),但并非所有 RPC 都必须使用 HTTP 协议。
深度解析
原理/机制
- HTTP:基于经典的 请求-响应 (Request-Response) 模型。通常使用文本格式(如 JSON/XML)序列化数据,协议头(Header)庞大且冗余(如 Cookie、Cache-Control 等 Web 特性字段),但其无状态和标准化的特点使其非常适合跨网络、跨语言的开放 API 场景。
- RPC:目标是实现 “透明远程过程调用”。一个完整的 RPC 调用过程包括:
- 客户端代理(Stub) 将方法名和参数序列化;
- 通过网络传输到服务器;
- 服务端骨架(Skeleton) 反序列化并调用实际方法;
- 将结果序列化返回。其底层通信协议通常追求更高的性能和紧凑性,例如使用自定义的二进制协议。
对比分析
| 维度 | HTTP (以 RESTful API 为例) | RPC (以典型框架如 Dubbo, gRPC 为例) |
|---|---|---|
| 通信协议 | 主要基于应用层的 HTTP/1.1 或 HTTP/2 协议。 | 通常基于传输层的 TCP 自定义二进制协议,或基于 HTTP/2 (如 gRPC)。 |
| 序列化 | 通常使用人类可读的 JSON、XML 等文本格式。序列化/反序列化开销较大。 | 通常使用高效的二进制格式,如 Protobuf、Hessian、Kryo。体积小,速度快。 |
| 性能 | 协议头较大,序列化效率较低,性能开销相对较高。HTTP/2 通过多路复用等特性大幅改善了性能。 | 专为高效内部通信设计,协议精简,序列化高效,性能通常优于 HTTP/1.1。 |
| 连接与交互 | 传统的 HTTP/1.1 是 “一问一答”,多个请求需要多个连接或串行。HTTP/2 支持连接复用和流。 | 通常支持连接复用、异步调用和流式处理,交互模式更灵活高效。 |
| 服务治理 | 需要额外集成组件(如客户端负载均衡器 Ribbon、服务发现 Eureka)来实现完整的治理。 | 框架原生集成了服务发现、负载均衡、熔断、限流等治理能力,开箱即用。 |
| 适用场景 | 对外的开放 API、需要被多种异构客户端(浏览器、移动端、第三方)调用的服务、简单快速的微服务原型。 | 大规模的内部微服务集群、对性能有极高要求的系统、需要复杂服务治理的分布式系统。 |
代码示例
一个简单的感受:调用一个 “获取用户信息” 的服务。
// 使用 HTTP (RestTemplate) 调用
// 开发者需要关注 URL、HTTP 方法、请求体/参数的组装
User user = restTemplate.getForObject("http://user-service/users/123", User.class);
// 使用 RPC (以 Dubbo 接口为例)
// 开发者像调用本地接口一样直接调用,框架隐藏了所有网络细节
@Reference
private UserService userService; // 远程服务的本地代理
public User getUser() {
return userService.getUserById(123L); // 看起来和本地调用无异
}
最佳实践与常见误区
- 最佳实践:
- 内外有别:对公网暴露的 API 优先使用 HTTP (RESTful),因其标准、通用、易于调试(用 curl 或浏览器即可)、防火墙友好。内部服务间调用,尤其是性能敏感、调用链路长的场景,优先考虑 RPC 以获得更好的性能和治理能力。
- 不唯技术论:技术选型需权衡团队技术栈、维护成本、生态集成度。Spring Cloud 生态的 OpenFeign(基于 HTTP)在中小规模下,凭借其与 Spring 的无缝集成,开发体验和效率可能优于引入一套独立的 RPC 框架。
- 常见误区:
- 误区一:HTTP 和 RPC 是完全对立的。实际上,gRPC 就是一个完美的反例,它既是强大的 RPC 框架,又使用 HTTP/2 作为传输协议,结合了二者的优势。
- 误区二:HTTP 性能一定差。HTTP/2 在性能上有了质的飞跃(头部压缩、多路复用、服务端推送),使其在不少场景下足以替代传统的 RPC 协议。
- 误区三:RPC 一定比 HTTP 复杂。对于调用方开发者而言,RPC 的接口式编程模型反而更简单直观。复杂性主要转移到了框架的部署和维护上。
总结
HTTP 是通用网络协议,适合构建开放、标准化的 Web API;而 RPC 是远程调用框架模式,旨在为内部服务提供高效、透明、治理完善的调用体验。在现代架构中,二者边界正在模糊(如 gRPC),关键在于根据 “场景”(内外网、性能要求) 和 “生态”(团队、基础设施) 做出最合适的选择。