NiceOffer

八股文解析

RPC 和 HTTP 调用有什么区别?微服务里怎么选?

RPC微服务八股文

一句话结论

RPC 是面向服务调用的二进制通信协议,HTTP 是面向资源的文本协议;微服务内部优先 RPC,对外暴露优先 HTTP。

面试标准答法

1. 本质差异:通信模型 vs 协议形态

RPC(Remote Procedure Call) 的核心思想是让远程调用看起来像本地调用。它屏蔽了网络细节,客户端调用一个本地方法,底层自动完成序列化、传输、反序列化、服务寻址。关键点:

  • 传输层:通常基于 TCP(也有 UDP/HTTP 变体),但 RPC 的协议头是自定义二进制格式(如 Dubbo 协议头 16 字节,含 magic、serialization id、status、request id 等字段)
  • 序列化:采用紧凑二进制(Hessian2、Protobuf、Kryo),体积小、解析快
  • 连接管理长连接 + 连接池,避免频繁三次握手
  • 服务发现:依赖注册中心(Nacos/Zookeeper),客户端本地缓存服务列表,通过负载均衡(随机/轮询/一致性哈希)选择节点
  • 超时与重试:客户端可配置超时时间,失败后自动重试(需注意幂等性)

HTTP 调用 是标准的请求-响应模型,基于 HTTP 协议(文本协议)。关键点:

  • 协议头:ASCII 文本,包含 method、path、headers、body
  • 序列化:通常是 JSON/XML,可读性强但体积大
  • 连接管理:HTTP/1.1 支持 keep-alive 复用连接,但HTTP/2 才真正支持多路复用(stream 概念)
  • 服务发现:通常通过 DNS + 负载均衡器(Nginx/LB),或服务网格(Istio)的 sidecar 代理
  • 语义:自带 GET/POST/PUT/DELETE 等 HTTP 方法,天然对应 CRUD 操作

2. 核心机制对比

维度RPC(以 Dubbo 为例)HTTP(以 Spring Cloud 为例)
协议格式自定义二进制头 + 序列化 body文本协议(HTTP/1.1)或二进制帧(HTTP/2)
序列化Hessian2/Protobuf(平均 100-200 字节)JSON(平均 500-1000 字节)
连接方式长连接池,连接复用率 90%+HTTP/1.1 keep-alive,HTTP/2 多路复用
性能单次调用 RTT 约 0.5-2ms单次调用 RTT 约 2-10ms(含 HTTP 头解析)
服务发现注册中心(Nacos/ZK),客户端直连DNS/LB,或网关路由
负载均衡客户端内置(权重/最小活跃数)服务端负载均衡(Nginx/LB)
超时控制客户端显式配置(如 3s)依赖 HTTP 层或网关配置
可观测性需额外集成(如 SkyWalking)天然支持 HTTP 状态码、日志
跨语言需支持多语言 SDK(如 gRPC 支持多语言)任何语言天然支持
调试需工具(如 Postman 插件)浏览器/curl 直接调试

3. 微服务里的选择逻辑

内部服务间调用(北向流量):优先 RPC

  • 性能敏感:高 QPS 场景下,RPC 的二进制协议 + 长连接能节省 30%-50% 的带宽和延迟
  • 服务治理:RPC 框架(Dubbo/gRPC)内置熔断、限流、降级、链路追踪,无需额外组件
  • 强类型约束:通过 IDL(Interface Definition Language)定义接口,编译期校验,避免运行时类型错误

对外暴露(南向流量):必须 HTTP

  • 客户端兼容性:浏览器、移动端、第三方系统只认 HTTP/HTTPS
  • 标准语义:RESTful 风格天然适合资源型接口,便于缓存、CDN 加速
  • 防火墙穿透:HTTP 端口(80/443)通常不会被防火墙拦截,RPC 自定义端口可能被阻断

混合架构(主流实践)

外部客户端 → API 网关(HTTP) → 内部服务(RPC 调用) → 下游服务(RPC)

网关负责协议转换(HTTP → RPC),内部服务间全部走 RPC。典型如:Spring Cloud Gateway(HTTP)→ Dubbo 服务(RPC)。

常见追问

追问回答要点
「RPC 一定比 HTTP 快吗?」不一定。HTTP/2 多路复用 + Protobuf 序列化后,性能差距缩小到 10%-20%。RPC 的优势在于连接复用和协议头精简,但如果是低频调用(如管理接口),HTTP 足够
「gRPC 是 RPC 还是 HTTP?」gRPC 是 RPC 框架,但底层走 HTTP/2 协议。它用 HTTP/2 的 stream 承载二进制帧,既保留了 RPC 的高效,又获得了 HTTP/2 的多路复用和流式传输能力
「如何保证 RPC 调用的幂等性?」幂等性靠业务层实现,与协议无关。常用方案:客户端生成全局唯一 requestId,服务端通过 Redis/DB 去重;或使用状态机保证重复请求返回相同结果
「RPC 框架如何做服务发现?」客户端启动时从注册中心拉取服务列表并缓存,订阅变更通知。客户端直连模式(Dubbo)比代理模式(Istio)延迟更低,但控制面复杂度更高

面试回答模板(30 秒版)

延伸准备

  1. HTTP/2 对 RPC 的冲击:HTTP/2 的多路复用 + 头部压缩(HPACK)让 HTTP 协议的性能接近二进制 RPC。可以对比 gRPC(基于 HTTP/2)和 Dubbo(基于 TCP 自定义协议)的选型差异,体现对协议演进的认知。
  1. 服务网格(Service Mesh)下的协议选择:Istio/Linkerd 默认支持 HTTP/1.1、HTTP/2、gRPC,但对 Dubbo 自定义协议支持有限。如果团队用服务网格,需要考虑 RPC 框架的协议兼容性,或改走 gRPC。
  1. 序列化选型对比:JSON(可读性)、Protobuf(性能+压缩比)、Hessian2(Java 生态兼容性)、Kryo(极致性能但需注册类)。能说出每种序列化的适用场景,说明你对 RPC 底层有深入理解。

想系统备战大厂大模型/Agent 开发?NiceOffer 提供 SDE+LLM 双轨 1v1 陪跑,合同保底 40w 年薪,文末扫码咨询。