核心概念
RPC(Remote Procedure Call,远程过程调用) 是一种通信机制,允许程序像调用本地方法一样调用远程服务器上的方法。它屏蔽了底层网络通信的复杂性,使得分布式系统开发更加简单。
HTTP(HyperText Transfer Protocol) 是应用层协议,定义了客户端和服务器之间请求和响应的标准格式。
本质区别:RPC 是一种调用方式(可基于多种传输协议实现),HTTP 是一种传输协议。
核心区别
1. 功能定位
| 维度 | RPC | HTTP |
|---|---|---|
| 本质 | 远程调用框架 | 传输协议 |
| 目标 | 像调用本地方法一样调用远程服务 | 定义请求/响应格式的标准 |
| 抽象层次 | 更高层的调用抽象 | 底层的传输协议 |
2. 传输协议
RPC:
- 可基于 TCP(自定义协议)
- 可基于 HTTP/HTTP2
- Dubbo 默认使用 TCP 上的自定义协议
HTTP:
- 基于 TCP 协议
- 使用标准的 HTTP/1.1 或 HTTP/2 协议
// RPC 调用示例(Dubbo)
@Reference
private UserService userService;
public void test() {
// 像调用本地方法一样
User user = userService.getUserById(123L);
}
// HTTP 调用示例(RestTemplate)
public void test() {
RestTemplate restTemplate = new RestTemplate();
// 需要构造 URL、处理序列化等
String url = "http://user-service/api/user/123";
User user = restTemplate.getForObject(url, User.class);
}
3. 序列化方式
RPC:
- 使用高效的二进制序列化(Hessian、Protobuf、Kryo)
- 数据体积小,传输速度快
- 可自定义序列化协议
HTTP:
- 通常使用 JSON、XML 等文本格式
- 数据体积大,可读性好
- 易于调试和跨语言
// RPC 序列化配置(Dubbo)
@Service(protocol = "dubbo", serialization = "hessian2")
public class UserServiceImpl implements UserService {
// ...
}
// HTTP 序列化(Spring MVC)
@RestController
public class UserController {
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
// 自动转为 JSON
return userService.getUserById(id);
}
}
4. 性能对比
RPC 更快的原因:
- 传输协议:基于 TCP 的自定义协议,减少了 HTTP 的头部开销
- 序列化:二进制序列化比 JSON 更高效
- 连接复用:长连接复用,减少握手开销
- 负载均衡:框架内置,无需额外跳转
HTTP 的优势:
- 通用性好,兼容性强
- 易于调试和监控
- 天然支持浏览器访问
- 生态丰富
典型应用场景
RPC 适用场景
// 1. 微服务内部调用(高性能要求)
@Service
public class OrderServiceImpl {
@Reference
private UserService userService; // RPC 调用
@Reference
private ProductService productService; // RPC 调用
public Order createOrder(CreateOrderDTO dto) {
User user = userService.getUser(dto.getUserId());
Product product = productService.getProduct(dto.getProductId());
// 业务逻辑
}
}
HTTP 适用场景
// 1. 对外开放的 API(需要跨语言、跨平台)
@RestController
@RequestMapping("/api/v1")
public class OpenApiController {
@PostMapping("/order")
public Result createOrder(@RequestBody CreateOrderRequest req) {
// 提供给第三方调用
return Result.success(orderService.create(req));
}
}
// 2. 前后端分离(浏览器访问)
@GetMapping("/user/profile")
public UserProfileVO getUserProfile() {
return userService.getProfile();
}
性能与架构考量
1. 性能优化
RPC 优化:
// 连接池配置
@Service(
connections = 10, // 每个服务提供者的最大连接数
actives = 20, // 每个服务的最大并发调用数
timeout = 3000 // 调用超时时间
)
public class UserServiceImpl implements UserService {
// ...
}
2. 混合使用
// 对内用 RPC,对外用 HTTP
@Service
public class BizServiceImpl {
// 内部服务调用,用 RPC
@Reference
private UserService userService;
// 调用外部系统,用 HTTP
@Autowired
private RestTemplate restTemplate;
public void process() {
User user = userService.getUser(123L); // RPC
String result = restTemplate.getForObject(
"http://third-party-api.com/api", String.class); // HTTP
}
}
答题总结
RPC 和 HTTP 的本质区别:
- 定位不同:
- RPC 是远程调用框架,强调”像本地调用一样”
- HTTP 是传输协议,定义请求/响应标准
- 实现差异:
- RPC:自定义协议 + 二进制序列化 + 长连接
- HTTP:标准协议 + JSON/XML + 短连接(HTTP/1.1 可 Keep-Alive)
- 性能对比:
- RPC 性能更高(协议开销小、序列化快)
- HTTP 通用性更好(跨语言、易调试)
- 应用场景:
- RPC:微服务内部高性能调用
- HTTP:对外 API、前后端分离、跨语言调用
- 典型框架:
- RPC:Dubbo、gRPC、Thrift
- HTTP:Spring MVC、Spring Cloud OpenFeign
面试技巧:强调 RPC 不是替代 HTTP,而是补充关系。在微服务架构中,内部用 RPC 保证性能,对外用 HTTP 保证兼容性,是常见的架构模式。