主题
RPC
介绍
一句话理解:
RPC 就是让你像调用本地函数一样调用远程服务的函数。不用管网络细节,框架帮你处理,你就是写代码,很直接。
RPC = Remote Procedure Call,远程过程调用。核心就是:屏蔽网络,让远程调用看起来像本地调用。
RESTful 和 RPC 的区别
最核心的差别:
| 维度 | RESTful | RPC |
|---|---|---|
| 设计思路 | 资源导向 | 行为导向 |
| 接口写法 | /users/{id} + GET/POST/PUT 等 | userService.getUser(id) 或 User.Get(id) |
| 返回格式 | 通常 JSON | 取决于框架(JSON、二进制等) |
| 学习成本 | 低,易于理解 | 中,需要了解框架细节 |
| 适用场景 | 对外 API、通用后台接口 | 内部微服务、跨服务调用 |
| 性能 | HTTP 开销较大 | 可用二进制协议,更高效 |
常见 RPC 框架
1. gRPC(Google)
用 Protocol Buffers 定义接口,支持多种语言,性能很好。
proto
service UserService {
rpc GetUser(UserId) returns (User);
rpc CreateUser(CreateUserRequest) returns (User);
}调用方式(Go 示例):
go
client.GetUser(context.Background(), &UserId{Id: 123})2. Dubbo(阿里)
Java 生态里很常见,特别是在微服务架构中。
接口定义:
java
public interface UserService {
User getUser(Long id);
void createUser(User user);
}3. JSON-RPC
最轻量的方案,直接用 HTTP + JSON。
请求:
json
{
"jsonrpc": "2.0",
"method": "userService.getUser",
"params": { "id": 123 },
"id": 1
}响应:
json
{
"jsonrpc": "2.0",
"result": {
"id": 123,
"name": "John"
},
"id": 1
}何时用 RPC,何时用 RESTful
用 RPC 的场景
- 内部微服务调用:多个内部服务之间频繁通信,需要高性能。
- 强类型契约:希望在编译时就发现类型错误,而不是运行时。
- 高吞吐量:比如秒杀、支付等对延迟敏感的场景。
- 私有协议:不需要浏览器友好,不需要缓存、代理等 HTTP 生态的特性。
用 RESTful 的场景
- 对外开放 API:给第三方调用,需要标准化、易理解。
- 通用后台接口:供前端或多种客户端调用。
- Web 标准生态:缓存、代理、负载均衡等都能直接用 HTTP 的特性。
- 快速迭代:不想被强类型约束,想灵活一些。
实战建议
微服务架构里的混用
很多互联网公司的做法:
- 对外:用 RESTful 接口(给 Web、App、第三方调用)。
- 对内:用 RPC 协议(内部服务间通信,一般是 gRPC 或 Dubbo)。
好处是各取所长:REST 简单通用,RPC 高效高性能。
选型建议
- 起步阶段:用 RESTful,简单直接。
- 单体服务优化:根据需要加 RPC 或缓存,不必急着拆。
- 微服务阶段:内部用 RPC(gRPC)或消息队列,对外用 REST。
- 高并发场景:考虑二进制 RPC 协议(gRPC)或异步消息。
补充:RPC 的常见坑
- 网络分区:RPC 调用可能超时、失败,需要降级、重试、熔断。
- 序列化陷阱:大对象序列化开销大,要注意传输数据大小。
- 版本兼容:服务更新时,接口版本管理容易出问题。
- 调试困难:RPC 比 HTTP 更难调试,需要专门的工具和日志。
总结
- RESTful:资源导向,HTTP 生态,易理解,对外开放。
- RPC:行为导向,高效高性能,强类型,适合内部微服务。
- 不是"谁替代谁",而是两种工具,场景不同选法不同。
- 互联网公司通常两者混用:对外 REST,对内 RPC。
