异步业务系统的一个常用实现模式

70 篇文章 0 订阅
37 篇文章 0 订阅

业务场景

一个系统,依赖很多外部系统的数据。对于一个请求过来,需要查询N个外部系统的数据,等全部数据拿到之后,做数据处理完之后,返回给请求端。如果依赖系统太长时间未返回,我们必须有一个超时响应机制返回给客户端。

简单方案

最简单的方案,就是通过同步的方式。一个客户端请求过来,假如依赖3个接口,则同步顺序的去请求三个接口,send1, recv1, send2, recv2, send3, recv3,拿到结果之后再做数据处理,再返回请求端

存在问题

因为是同步,所以每一步都需要等待,CPU阻塞在等待线程中无法做更多的事情。效率极低

改进方案

直观上能想到的就是把同步改成异步。那么刚好可以配合上linux内核提供的epoll异步事件机制使用。那么要把同步改成异步,需要满足哪些条件?
1、自身的系统和请求的系统协议,必须支持异步。
简单来说,就是协议上要支持回带字段,才能区分是哪一次的会话请求。至于一些同步的依赖系统,后续会讲如何解决这类问题,这里先假设所有系统都支持回带字段。

2、会话管理机制。一个请求过来之后,系统必须会每一次客户端的请求创建一次会话,并记录会话是否超时。如果有接口超时之后还未获得数据,则必须通知客户端请求超时。从业务侧则体现在,一个请求如果太久没有返回,那到时返回给我也没有什么意义了,需要支持一个最大超时时间来返回数据。

3、状态机。
每一个业务消息,他可能每次依赖的接口之间有顺序之分,或者没有顺序之分。

  • 场景1:可能依赖的三个接口,三个接口之间没有先后之分,可以同步并发请求。
  • 场景2:依赖的三个接口,可能接口2依赖接口1返回的数据,因此,这种情况下,对于会话是需要状态机的支持。通过一个状态机来管理一个会话的状态。

实现方案

1、异步消息回带,这里只需要系统接口层面的支持即可。通过在协议中约定某些字段,原封不动的返回即可,方便系统做异步。
2、状态机,这里通过一个整数值存状态即可简单实现。每一个会话建立的话,即为初始状态。按照业务逻辑进行请求。每次依赖的接口返回时,即做状态的检查与切换。
3、会话管理。
这里简单介绍一下会话管理的一个算法模型实现。
在这里插入图片描述
通过一个双向链表来管理会话。

  • 插入
    当一个新的请求过来的时候,在链表头部插入一个会话节点。时间复杂度为O(1)。
  • 删除
    当一个会话的状态机到终态的时候,因为知道会话id,能直接找到该会话的地址,所以要从双向链表中删除一个节点,也是O(1)时间复杂度。
  • 扫描过期
    对于超时机制的支持,这里可以通过从队尾进行定期扫描来解决问题。由于最新的节点是在队头不停的插入,所以整个双向链表是一个按时间新旧顺序排列的有序链表。我们只需要从链表的尾部扫描即可,扫描的时候,比较会话建立的时间与当前时间,超过超时时间即结束会话。直接扫描到第一个不超时的会话即完全队列的扫描任务。
    这个场景,刚好可以加到epoll_wait中的超时回调函数去完成

遗留问题

如果依赖的外部系统,不支持异步协议如何?
简单的解决思路,可以通过在本地调用端,写一个进程去做接口的转换。写一个简单的同步转异步服务。系统调用的时候,直接调用异步服务,转换服务再去请求同步的接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值