Skip to content

RPC

介绍

一句话理解:

RPC 就是让你像调用本地函数一样调用远程服务的函数。不用管网络细节,框架帮你处理,你就是写代码,很直接。

RPC = Remote Procedure Call,远程过程调用。核心就是:屏蔽网络,让远程调用看起来像本地调用。

RESTful 和 RPC 的区别

最核心的差别:

维度RESTfulRPC
设计思路资源导向行为导向
接口写法/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 高效高性能。

选型建议

  1. 起步阶段:用 RESTful,简单直接。
  2. 单体服务优化:根据需要加 RPC 或缓存,不必急着拆。
  3. 微服务阶段:内部用 RPC(gRPC)或消息队列,对外用 REST。
  4. 高并发场景:考虑二进制 RPC 协议(gRPC)或异步消息。

补充:RPC 的常见坑

  1. 网络分区:RPC 调用可能超时、失败,需要降级、重试、熔断。
  2. 序列化陷阱:大对象序列化开销大,要注意传输数据大小。
  3. 版本兼容:服务更新时,接口版本管理容易出问题。
  4. 调试困难:RPC 比 HTTP 更难调试,需要专门的工具和日志。

总结

  • RESTful:资源导向,HTTP 生态,易理解,对外开放。
  • RPC:行为导向,高效高性能,强类型,适合内部微服务。
  • 不是"谁替代谁",而是两种工具,场景不同选法不同。
  • 互联网公司通常两者混用:对外 REST,对内 RPC。

基于 MIT 许可发布