RPC 和 HTTP/REST 有什么区别?
简化版
严格说 RPC 和 HTTP 不是一个层面的东西——HTTP 是应用层协议,RPC 是一种「远程调用」的设计思想/框架,RPC 底层也可以用 HTTP(如 gRPC 基于 HTTP/2)。面试里的「RPC vs HTTP」通常指**「RPC 框架(如 Dubbo)」和「基于 HTTP 的 REST 接口」两种服务调用方式的对比**:RPC 通常用自定义 TCP 协议 + 高效二进制序列化(Protobuf/Hessian),性能高、面向方法调用、适合内部微服务间高频调用;HTTP/REST 用通用 HTTP 协议 + JSON,通用性好、跨语言跨平台、可读性强、适合对外开放 API 和跨团队,但性能相对低。
详细版
RPC(框架,如 Dubbo)vs HTTP/REST 对比:
| 维度 | RPC(Dubbo 等) | HTTP/REST |
|---|---|---|
| 协议 | 自定义 TCP 协议(或 HTTP/2) | HTTP/1.1(通用) |
| 序列化 | 二进制(Protobuf/Hessian/Kryo),高效 | 文本(JSON),可读但冗余 |
| 性能 | 高(协议精简、二进制小、长连接) | 相对低(文本大、HTTP 头冗余) |
| 调用风格 | 面向方法(像调本地方法) | 面向资源(URL + 动词 GET/POST) |
| 耦合度 | 较高(需共享接口/IDL) | 松(只依赖 URL 和数据格式) |
| 跨语言 | 需框架支持(gRPC/Thrift 好) | 天然跨语言、跨平台 |
| 可读性/调试 | 二进制不易读 | 文本可读,浏览器/Postman 直接调 |
| 适用 | 内部微服务高频调用 | 对外 API、跨团队、跨语言 |
注意:gRPC 是 RPC 框架但底层用 HTTP/2,所以「RPC vs HTTP」不是非此即彼——关键看协议效率、序列化方式、调用风格。
完整版教学
一、先澄清概念:不在一个维度
「RPC vs HTTP」这个对比其实不太严谨,因为它们不是同一维度的概念:
- HTTP 是一个应用层协议(规定了请求/响应的格式)。
- RPC 是一种远程调用的思想/模式,以及实现它的框架。
关键点:RPC 的底层传输,既可以用自定义的 TCP 协议,也可以用 HTTP。比如 gRPC 就是基于 HTTP/2 的 RPC 框架。所以说「RPC 不用 HTTP」是不准确的。
面试里问「RPC vs HTTP」,实际想问的是:「用 Dubbo 这类 RPC 框架」和「用基于 HTTP 的 RESTful 接口」这两种服务调用方式,有什么区别、怎么选。下面按这个理解展开。
二、协议与序列化:性能的根源
两者性能差异的根源在协议开销和序列化方式:
RPC 框架(如 Dubbo):
- 通常用自定义的、精简的 TCP 协议——协议头很小,没有 HTTP 那么多冗余的头部字段。
- 用二进制序列化(Protobuf、Hessian、Kryo)——把对象压成紧凑的二进制,体积小、序列化/反序列化快。
- 常用长连接复用,减少连接建立开销。
HTTP/REST:
- 用通用的 HTTP 协议——每个请求带一堆 HTTP 头(Host、User-Agent、Content-Type…),头部冗余较大。
- 通常用 JSON(文本格式)序列化——可读性好,但体积大、解析慢(文本比二进制冗余)。
- HTTP/1.1 默认每次请求响应,虽然可以 keep-alive,但效率不如 RPC 的长连接复用。
所以RPC 通常比 HTTP/REST 性能更高(协议精简 + 二进制序列化 + 长连接),这也是内部微服务高频调用倾向用 RPC 的原因。
三、调用风格:面向方法 vs 面向资源
RPC 是面向方法的:你调用的是一个「方法」——userService.getUser(1),就像调本地方法,语义是「执行某个操作」。接口和方法是调用的核心。
REST 是面向资源的:你操作的是「资源」——用 URL 定位资源(/users/1),用 HTTP 动词表达操作(GET 查、POST 建、PUT 改、DELETE 删)。语义是「对某个资源做某种标准操作」。
风格差异带来使用感受不同:RPC 更像「调函数」,直观贴近编程;REST 更规范统一(一套 URL + 动词的约定),但表达复杂操作时不如方法调用灵活。
四、耦合度与跨语言
耦合度:
- RPC 耦合较高:客户端和服务端通常要共享接口定义(Java 接口 jar 包,或 gRPC/Thrift 的 IDL 文件)。接口变了两边都要更新,耦合紧一些。
- REST 耦合较松:客户端只依赖 URL 和数据格式(JSON 字段),不需要共享代码,双方约定好接口文档即可,耦合松。
跨语言:
- REST 天然跨语言跨平台:HTTP + JSON 是通用标准,任何语言、任何平台都能轻松调用,浏览器、Postman、curl 直接就能测。
- RPC 的跨语言看框架:Dubbo 早期主要面向 Java;但 gRPC、Thrift 通过 IDL 生成多语言代码,跨语言能力也很好。
五、如何选型:内部用 RPC,对外用 HTTP
综合下来,选型原则通常是:
内部微服务之间 → 倾向 RPC:
- 调用频繁、对性能敏感,RPC 的高性能优势明显。
- 内部服务,接口相对可控,共享接口定义的耦合可接受。
- 例:订单服务调用库存服务、用户服务,用 Dubbo/gRPC。
对外开放 API、跨团队、跨语言 → 倾向 HTTP/REST:
- 需要通用性、跨语言、易调试、松耦合。
- 对外提供给第三方、前端、其他团队,HTTP/JSON 门槛最低、最通用。
- 例:开放平台 API、前后端交互、给合作方的接口。
现实中大型系统两者都用:内部服务间 RPC,对外和前端 HTTP。gRPC 的出现也让「高性能 + 基于 HTTP/2 + 跨语言」兼得,模糊了两者界限。
六、常见误区与追问
这道题面试时最容易丢分的地方,是把「RPC 与 HTTP API 对比」答成一段泛泛的组件介绍。更稳的答法是先给结论,再沿着 远程调用链路 拆清楚流程,最后补上异常场景、数字边界和选型取舍。
| 回答层次 | 要讲清的内容 | 容易漏掉的边界 |
|---|---|---|
| 核心定义 | RPC 强调服务间方法调用和治理能力,HTTP API 强调资源接口、开放性和通用兼容 | 不要停在名词解释 |
| 流程机制 | 判断调用对象是内部服务还是外部客户端 -> 判断是否需要强治理和接口契约 -> 评估跨语言和调试成本 -> 选择 RPC、HTTP REST 或 gRPC over HTTP/2 | 说明谁触发、谁存储、谁通知、谁兜底 |
| 工程取舍 | 内部高频服务调用可用 gRPC/Dubbo 降低协议和序列化开销,对外开放接口通常优先 HTTP/REST | RPC 让调用写法像本地方法,但失败语义、网络延迟和版本兼容必须按远程系统处理 |
RPC 与 HTTP API 对比 面试拆解:
1. 判断调用对象是内部服务还是外部客户端
2. 判断是否需要强治理和接口契约
3. 评估跨语言和调试成本
4. 选择 RPC、HTTP REST 或 gRPC over HTTP/2
记忆钩子:先拆代理、序列化、传输、寻址、容错,再说明超时、重试、幂等这些工程边界;回答时一定要落到题目中的「RPC 与 HTTP API 对比」,不要把相邻中间件的能力混着讲。
- 误区:RPC 一定比 HTTP 快。 性能取决于协议、序列化、连接复用和实现,HTTP/2 加 Protobuf 的 gRPC 也属于 RPC 形态。
- 误区:HTTP 不能做服务治理。 HTTP 也能配合网关、注册发现和限流做治理,只是生态和抽象方式不同。
- 误区:对外接口也应该直接暴露 Dubbo。 外部生态更适合 HTTP/REST 或 GraphQL,兼容性、调试和安全边界更清晰。
- 追问:什么时候选 RPC? 内部服务高频调用、需要强类型契约、负载均衡、容错和连接治理时。
- 追问:什么时候选 HTTP API? 面向浏览器、第三方开放平台、弱语言绑定或需要通用调试工具时。
- 追问:gRPC 属于 HTTP 还是 RPC? 它是基于 HTTP/2 传输和 Protobuf IDL 的 RPC 框架。
七、加强记忆
「RPC vs HTTP」不严谨——HTTP 是协议、RPC 是调用思想/框架,RPC 底层也能用 HTTP(gRPC 基于 HTTP/2)。面试实指「RPC 框架(Dubbo)vs 基于 HTTP 的 REST」:RPC 用自定义 TCP 协议 + 二进制序列化(Protobuf/Hessian)+ 长连接,性能高、面向方法、耦合较高(共享接口/IDL),适合内部微服务高频调用;HTTP/REST 用通用 HTTP + JSON,通用性强、跨语言、松耦合、易调试但性能相对低、面向资源(URL+动词),适合对外 API、跨团队跨语言。选型口诀:内部服务重性能用 RPC、对外开放重通用用 HTTP;gRPC 兼得高性能与跨语言。