架构设计之异步请求怎么同步处理
这篇文章主要讲解了"架构设计之异步请求怎么同步处理",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"架构设计之异步请求怎么同步处理"吧!
全文摘要:
异步给现有架构带来的问题
Dubbo 异步转同步解决方法
异步转同步架构设计方案
0x00. 前言
现有一个系统,整体架构如下所示:
这是一个很常见的同步设计方案,上游系统需要等待下游系统接口返回调用结果。
现在需要接入另外一个第三方服务 B,该服务与服务 A 最大区别在于,这是一个异步 API
。调用之后,仅仅返回受理成功,处理结果后续通过异步通知返回。
接入之后,整体架构如下所示:
默认情况下,Dubbo 支持同步调用方式,这里将会创建 DefaultFuture
对象。
业务线程调用 DefaultFuture#get
方法进入阻塞。这段代码比较简单,通过调用 Condition#await
阻塞线层。
0x02. 转发方案设计
根据 Dubbo 解决思路,问题 1 解决办法就比较简单了。具体流程如下:
通信服务 B 内部生成一个唯一请求 ID ,发给第三方服务
若请求成功,内部版使用
Map
存储对应关系,并使业务线程阻塞等待通信服务 B 收到异步通知结果,通过 ID 查找对应业务线程,唤醒的相应的线程
这个设计过程需要注意设置合理的超时时间,这个超时时间需要考虑远程服务调用耗时,可以参考如下公式:
业务线程等待时间=通信服务 B 接口的超时时间 - 调用第三方服务 B 接口消耗时间
这里就不贴出具体的代码,详细代码参考 Dubbo DefaultFuture
。
接下来重点看下通知服务如何将结果转发给正确的通信服务 B 的节点。这里想到两种方案:
SocketServer 方案
MQ 方案
2.1 SocketServer
通信服务 B 使用 SocketServer 构建一个服务接收程序,当通知接收程序收到第三方服务 B 通知时,通过 Socket
将结果转发给通信服务 B。
整个系统架构如下所示:
通知接收程序收到异步通知之后,直接将结果发送到 MQ
。
通信服务 B 开启广播消费模式,拉取 MQ
消息。
通信服务 B_1 拉取消息,通过请求 ID 映射关系,没找到内部等待的线程,知道这不是自己的等待消息,于是 B_1 直接丢弃即可。
通信服务 B_2 拉取消息,通过请求 ID 映射关系,顺利找到正在等待的线程,然后可以唤醒等待线程,返回最后的结果。
对比 SocketServer
方案,MQ
方案整体流程比较简单,编程难度低,也没用存在特殊的配置。
不过这个方案十分依赖 MQ
消息实时性,若 MQ
消息投递延迟很高,这就会导致通信服务 B 业务线程超时苏醒,业务异常返回。
这里我们选择使用 RocketMQ
,长轮询 Pull
方式,可保证消息非常实时,
感谢各位的阅读,以上就是"架构设计之异步请求怎么同步处理"的内容了,经过本文的学习后,相信大家对架构设计之异步请求怎么同步处理这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!