本文创意来自一次业务需求,这次需要接入一个第三方外部服务。由于这个服务只提供异步 API,为了不影响现有系统同步处理的方式,接入该外部服务时,应用对外屏蔽这种差异,内部实现异步请求同步。
全文摘要:
- 异步给现有架构带来的问题
- Dubbo 异步转同步解决方法
- 异步转同步架构设计方案
0x00. 前言
现有一个系统,整体架构如下所示:
这是一个很常见的同步设计方案,上游系统需要等待下游系统接口返回调用结果。
现在需要接入另外一个第三方服务 B,该服务与服务 A 最大区别在于,这是一个异步 API
。调用之后,仅仅返回受理成功,处理结果后续通过异步通知返回。
接入之后,整体架构如下所示:
由于网络隔离策略,通知接收程序与通信服务需要单独分开部署。若没此要求,可以将通信服务 B 与通知接收程序合并成一个应用。
另外图中所有应用采用双节点部署。
为了不影响 OpenAPI
上游系统同步处理逻辑,通信服务 B 调用第三方服务之后,不能立刻返回,需要等待结果通知,拿到具体返回结果。这就需要通信服务 B 内部将异步转为同步。
这就是一个典型的异步转同步问题,整个过程涉及两个问题。
- 通信服务 B 业务线程如何进入等待状态?又如何唤醒正确等待线程?
- 由于通信服务 B 双节点部署,通知接收程序如何将结果转发到正在等待处理的节点?
问题 1 的解决方案参考了 Dubbo 设计思路。
我们在使用 Dubbo 调用远程服务时,默认情况下,这是一种阻塞式调用方式,即 Consumer 端代码一直阻塞等待,直到 Provider 端返回为止。
由于 Dubbo 底层基于 Netty
发送网