RPC远程调用详解
RPC(Remote Procedure Call,远程过程调用)是一种计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。如果涉及的软件采用面向对象编程,那么 RPC 亦可称作远程调用或远程方法调用。
一、RPC 的基本概念
在单机应用中,调用一个函数非常简单,直接通过函数指针或引用即可。但在分布式系统中,服务部署在不同的服务器上,如何像调用本地函数一样调用远程服务器上的函数呢?这就是 RPC 要解决的问题。
RPC 的核心目标是:让远程服务调用看起来像本地调用一样简单。
二、RPC 的工作原理
RPC 的实现过程通常包含以下几个关键组件:
- Client(客户端):服务的调用方。
- Client Stub(客户端存根):存放服务端的地址消息,将客户端的请求参数打包成网络消息,再通过网络发送给服务端。
- Network Service(网络传输):底层传输,可以是 TCP 或 HTTP。
- Server Stub(服务端存根):接收客户端发送过来的消息,将消息解包,并调用本地的方法。
- Server(服务端):服务的提供方。
调用流程
- 客户端调用客户端 Stub(就像调用本地方法一样)。
- 客户端 Stub 将参数打包(序列化)并通过网络发送给服务端。
- 服务端 Stub 接收到消息后,将参数解包(反序列化)。
- 服务端 Stub 调用本地服务方法。
- 服务端执行方法并将结果返回给服务端 Stub。
- 服务端 Stub 将结果打包(序列化)并通过网络发送给客户端。
- 客户端 Stub 接收到消息,将结果解包(反序列化)。
- 客户端得到最终结果。
三、RPC 与 REST 的区别
REST(Representational State Transfer)是一种架构风格,通常基于 HTTP 协议。
| 特性 | RPC | REST |
|---|---|---|
| 核心思想 | 动作(Action),强调过程 | 资源(Resource),强调状态 |
| 传输协议 | 通常基于 TCP 或 HTTP/2 | 基于 HTTP/1.1 或 HTTP/2 |
| 数据格式 | Protobuf, Thrift, Hessian 等二进制格式(高效) | JSON, XML 等文本格式(可读性好) |
| 性能 | 高(序列化/反序列化快,包体小) | 相对较低 |
| 适用场景 | 内部微服务之间的高性能通信 | 对外 API,异构系统集成 |
四、常见的 RPC 框架
- gRPC:由 Google 开发,基于 HTTP/2 和 Protobuf,支持多语言,性能优异。
- Dubbo:阿里巴巴开源的高性能 Java RPC 框架,提供了完善的服务治理功能。
- Thrift:Facebook 开发的跨语言 RPC 框架。
- Spring Cloud Feign:基于 HTTP 的伪 RPC 框架,使用起来非常方便,但本质上是 HTTP 调用。
五、RPC 的优缺点
优点
- 简单易用:开发者无需关注底层网络通信细节。
- 高效:通常使用二进制序列化和 TCP 协议,性能优于 HTTP+JSON。
- 强类型:通常有 IDL(接口定义语言)约束,类型安全。
缺点
- 耦合性:客户端和服务端需要依赖相同的接口定义。
- 调试困难:二进制协议不如 JSON 直观,抓包调试相对麻烦。
- 复杂性:引入了服务发现、负载均衡、熔断降级等服务治理问题。
六、总结
RPC 是构建分布式系统和微服务架构的基石。选择合适的 RPC 框架(如 gRPC 或 Dubbo)可以显著提高系统的性能和开发效率。但在设计系统时,也需要权衡 RPC 和 REST 的适用场景,通常内部服务间使用 RPC,对外接口使用 REST。