1. 设计目标与核心思想
-
RPC
旨在透明化远程调用 ,使开发者像调用本地方法一样调用远程服务。核心是隐藏网络细节 (如序列化、传输、路由),强调效率 和低延迟,适用于内部服务间通信。
-
HTTP
作为通用的应用层协议 ,设计目标是标准化客户端与服务器的资源交互 (如Web页面、API)。基于请求-响应模型 ,强调可扩展性 、兼容性 和可读性,适合对外暴露服务。
2. 协议特性
-
协议格式
- RPC :通常采用二进制协议(如Protobuf、Thrift),数据紧凑、解析高效。部分框架(如gRPC)基于HTTP/2,利用其多路复用等特性,但数据仍为二进制格式。
- HTTP :早期基于文本格式(如HTTP/1.1的明文头与JSON/XML),可读性强但效率低;HTTP/2引入二进制分帧,性能提升,但语义仍围绕资源操作(URL、方法、状态码)。
-
传输协议
- RPC:可直接基于TCP/UDP(如Dubbo),或结合HTTP/2(如gRPC)。
- HTTP:默认基于TCP,严格遵循应用层协议规范。
3. 性能对比
-
序列化效率
RPC的二进制协议(如Protobuf)序列化速度快、体积小;HTTP的JSON/XML体积大、解析开销高。
-
网络开销
RPC通过长连接、连接池减少握手开销;HTTP/1.1的短连接有较高延迟,但HTTP/2的多路复用缩小了差距。
-
典型场景
- RPC:微服务间高频调用(如订单服务调用库存服务)。
- HTTP:跨系统、浏览器/移动端API交互。
4. 功能与生态
-
服务治理
- RPC:内置服务发现、负载均衡、熔断降级(如Dubbo的注册中心、gRPC的健康检查)。
- HTTP:依赖网关(如Nginx、Kong)或服务网格(如Istio)实现治理功能。
-
跨语言支持
- HTTP:天然支持多语言(任何语言均可处理HTTP请求)。
- RPC:需通过IDL(接口定义语言)生成多语言客户端(如Protobuf定义接口)。
5. 开发体验
-
调用方式
- RPC :面向方法调用(如
userService.getUser(id)
),隐藏网络细节。 - HTTP :面向资源操作(如
GET /users/{id}
),需处理状态码、Header等。
- RPC :面向方法调用(如
-
接口定义
- RPC:强依赖接口规范(如Protobuf文件),需预生成代码。
- HTTP:通常通过文档(如OpenAPI)约定接口,灵活性高但易不一致。
6. 适用场景
场景 | RPC | HTTP |
---|---|---|
内部服务通信 | ✅ 高频调用、低延迟需求 | ❌ 性能开销较高 |
对外暴露API | ❌ 需额外网关适配 | ✅ 浏览器、移动端友好 |
跨语言交互 | ⚠️ 需生成多语言代码 | ✅ 天然支持 |
实时流传输 | ✅ 支持双向流(如gRPC流式调用) | ❌ HTTP/2支持有限 |
总结:如何选择?
-
选RPC :
内部服务间通信、追求高性能、需完善的服务治理、强类型接口约束。
-
选HTTP :
对外提供API、需要广泛兼容性(如浏览器支持)、快速迭代且接口变动频繁。
补充说明
- 融合趋势:现代框架(如gRPC)结合HTTP/2与二进制协议,兼顾性能与通用性;REST over HTTP也可通过优化(如HTTP/2+Protobuf)提升效率。
- 协议非对立:RPC是一种设计模式,HTTP是具体协议,两者可结合使用(如gRPC基于HTTP/2)。选择时需结合实际架构需求,而非绝对二选一。