认识 RPC 的不同模式

文章目录

  • 0.前言
  • [1.核心 RPC 模式对比](#1.核心 RPC 模式对比)
  • 2.模式详解
    • [2.1 同步模式 (Request-Reply)](#2.1 同步模式 (Request-Reply))
    • [2.2 异步模式 (Future/Promise)](#2.2 异步模式 (Future/Promise))
    • [2.3 单向调用 (One-way)](#2.3 单向调用 (One-way))
    • [2.4 回调模式 (Callback)](#2.4 回调模式 (Callback))
  • 3.如何选择?
  • 4.补充阅读
  • 参考文献

0.前言

远程过程调用(RPC,Remote Procedure Call)的核心思想是让调用远程服务像调用本地函数一样自然。但在工程实践中,根据不同的业务需求和技术场景,RPC 演化出了多种实现模式。

这里整理了四种最核心的模式,可以帮助你建立一个清晰的认知框架。

1.核心 RPC 模式对比

这四种模式各有侧重,简单来说,同步模式异步模式 解决的是通信的效率 问题,而单向调用回调模式 解决的是通信的交互形式问题。

模式 核心机制 特点 适用场景
同步模式 请求-响应 阻塞等待 实现简单、逻辑直观;但客户端必须等待,可能造成线程阻塞。 普通Web后端、BFF层、读写数据库等大部分常规业务。
异步模式 基于 Future/Promise 非阻塞 高吞吐、资源利用率高;但编程模型相对复杂。 高并发服务、IO密集型任务、调用链较长的场景。
单向调用 请求-only 无需响应 客户端发送后即返回,开销极小;可靠性低,无法感知服务端状态。 日志上报、监控指标采集、非关键通知。
回调模式 双向异步 结果通知 适合长时任务,客户端无需轮询;实现复杂,需要额外处理回调。 AI推理任务、报表生成、订单异步处理。

2.模式详解

2.1 同步模式 (Request-Reply)

这是最基础的RPC模式,由 Birrell 和 Nelson 在 1984 年的经典论文中首次系统阐述 1。客户端发起调用后,线程会阻塞,一直等待服务器返回结果或超时,才继续执行。

java 复制代码
// 客户端代码会在此等待1秒钟,直到服务端返回结果
Response res = rpcClient.send(request);

它最大的优点是编程模型简单,符合直觉,在大部分业务逻辑简单的场景(如HTTP调用、数据库操作)是首选。缺点是当服务端处理慢时,客户端线程会被长时间占用,影响系统整体吞吐量。

2.2 异步模式 (Future/Promise)

客户端发起调用后,会立即返回一个 FuturePromise 对象,不会阻塞当前线程。你可以在稍后通过这个对象获取最终结果。Ananda 等人于 1992 年发表了关于异步 RPC 的系统性综述 2,对这一模式进行了详细分类。

java 复制代码
Future<Response> future = rpcClient.asyncSend(request);
// 这里可以做别的事情,不阻塞
doOtherThings();
// 最后再尝试获取结果,如果未完成则阻塞等待
Response res = future.get();

这种模式能有效提升系统的并发能力,非常适合IO密集型或服务调用链较长的场景。

2.3 单向调用 (One-way)

客户端发送请求后,完全不关心服务端是否收到或如何处理,立刻返回。这是最轻量级的模式,几乎没有响应开销。

java 复制代码
// 调用发出后立刻返回,不等待任何响应
rpcClient.onewaySend(logRequest);

适用于日志上报、监控打点等可靠性要求不高、但对性能有极致要求的场景。

2.4 回调模式 (Callback)

这是异步模式的一种实现。客户端发起调用时,会附带一个回调函数。当服务端处理完成并返回结果时,这个回调函数会被自动触发。

java 复制代码
rpcClient.asyncSend(request, new Callback() {
    public void onSuccess(Response res) { handle(res); }
    public void onFailure(Throwable t) { handleError(t); }
});
// 调用发出后立刻返回,不阻塞
doOtherThings();

这种方式在GUI编程和JavaScript中非常常见。在RPC中,它非常适合处理耗时较长的任务,客户端无需一直等待,通过回调优雅地处理最终结果。

工业实践参考:SOFARPC 框架对这四种调用模式(同步、Future、Callback、单向)均有完整的实现支持 34

3.如何选择?

你可以根据自己的需求,参考下面的思路来选择合适的模式:

  • 你的业务逻辑是简单的请求-响应吗? ➡️ 同步模式。它是默认选择,简单直接。
  • 你的系统需要处理海量并发请求吗? ➡️ 异步模式 (Future)。它能有效提升吞吐量。
  • 你需要发送日志或监控数据,并且不能影响主流程吗? ➡️ 单向调用
  • 你需要调用一个耗时很长的任务,并且不想阻塞线程吗? ➡️ 回调模式

4.补充阅读


参考文献

1 Birrell, A.D., Nelson, B.J. Implementing remote procedure calls. ACM Transactions on Computer Systems , 2(1), 39--59 (1984).

🔗 https://dl.acm.org/doi/10.1145/2080.357392

2 Ananda, A.L., Tay, B.H., Koh, E.K. A survey of asynchronous remote procedure calls. ACM SIGOPS Operating Systems Review , 26(2), 92--109 (1992).

🔗 https://dl.acm.org/doi/10.1145/382244.382832

3 SOFARPC 官方文档:同步异步实现剖析。阿里云开发者社区,2018.

🔗 https://developer.aliyun.com/article/663767

4 SOFARPC 线程模型剖析:同步异步与线程模型详解。阿里云开发者社区,2018.

🔗 https://developer.aliyun.com/article/662498

相关推荐
AsulTop6 天前
精简版 OpenWrt/LEDE uhttpd/rpc/mod-rpc/ Ubus Json-RPC 从0修复直到可用
rpc·路由器·openwrt·lede·uhttpd·ubus修复
小胖xiaopangss16 天前
BRpc使用
c++·rpc
zhuzicc16 天前
Dubbo @Autowired 注入同模块接口,到底走的是本地调用还是 RPC?源码给你答案(Dubbo @Service注解的双重注册机制)
rpc·autowired·dubbo·依赖注入·java面试·spring ioc·dubbo源码分析
leo_yu_yty17 天前
Go语言分布式计算(RPC入门)
网络·网络协议·rpc
衣乌安、17 天前
JSON-RPC协议
网络协议·rpc·json
276695829218 天前
泡泡玛特app 腾讯企业加固/支付宝加固脱修frida rpc调用
网络·网络协议·rpc·frida·泡泡玛特·ppmt·泡泡玛特app-rpc调用
白露与泡影20 天前
为什么 RPC 要比 HTTP 更快?我:之前项目只用过 HTTP...
网络协议·http·rpc
skywalker_1121 天前
SpringBoot速通(实战教学)
java·spring boot·redis·rpc·ssm·mybatis-plus
旧物有情21 天前
C#异步编程
网络·rpc·c#
xyz_CDragon21 天前
把旧电脑变成AI算力:llama.cpp RPC 局域网分布式推理验证与实战
人工智能·分布式·python·rpc·llama