环节 | RPC | HTTP API |
---|---|---|
调用方式 | 调用远程函数/方法(如 userService.getUser(123) ) |
调用远程端点(如 GET /users/123 ) |
参数传递 | 通过序列化直接传递编程语言对象 | 通过URL参数、Header或Body传递结构化数据 |
网络传输 | 通常基于TCP/UDP + 二进制协议(如gRPC的HTTP/2) | 基于HTTP/HTTPS文本协议 |
数据封装 | 由框架自动处理序列化/反序列化 | 需手动处理JSON/XML转换 |
服务发现 | 内置服务注册发现机制(如Nacos) | 依赖外部负载均衡器或DNS |
表面流程:
客户端传参 → 网络传输 → 服务端执行 → 返回结果
两者一致
❗ 核心差异:抽象层级不同(RPC抽象了网络通信,API需显式处理)
特性 | RPC框架(如gRPC/Dubbo) | HTTP API(如RESTful) |
---|---|---|
协议层 | 自定义二进制协议(高效但封闭) | HTTP协议(通用但冗余) |
序列化 | Protobuf/Thrift(高性能二进制) | JSON/XML(文本,可读性好) |
连接管理 | 长连接+连接池(低延迟) | 通常短连接(高并发时开销大) |
服务治理 | 内置负载均衡、熔断、链路追踪 | 需依赖API网关实现 |
跨语言支持 | 需各语言实现客户端存根 | 天然支持(任何语言都能发HTTP请求) |
// RPC调用示例(客户端代码)
User user = userService.getUser(123); // 像调用本地方法
// HTTP API调用示例(客户端代码)
HttpResponse response = httpClient.execute(
new HttpGet("http://service/user/123") // 显式网络操作
);
User user = parseJson(response.getBody()); // 手动反序列化
以下场景优先选择RPC:
微服务集群内部通信
需要精细服务治理
强类型接口约束
// user_service.proto
service UserService {
rpc GetUser (GetUserRequest) returns (User) {}
}
message GetUserRequest {
int32 user_id = 1;
}
流式数据传输
场景 | 推荐方案 | 案例说明 |
---|---|---|
前端/移动端访问后端 | HTTP API | 浏览器调用 RESTful API |
Java微服务集群内部调用 | Dubbo RPC | 订单服务调用库存服务 |
跨语言服务集成(C++/Go) | gRPC | Go编写的算法服务供Python调用 |
实时数据推送 | gRPC流式RPC | 股票价格实时更新 |
关键结论:
HTTP API是语言,RPC是方言—— RPC在特定场景(高性能服务间调用)通过协议优化和框架封装,解决了通用HTTP API的性能和开发效率问题。选择时需权衡开发效率、性能需求、系统复杂度。