详情-思想者
分布式系统超时管理系统
发布于 2018-12-25 ,0条评论,133次浏览

一、诞生背景

以某公司支付系统为例,支付链路为A-->B-->C-->D-->E。多个应用之前以类似于链表的方式进行交互,上下游系统属于强依赖关系,且都是异步MQ交互。A系统是面向前端客户的,即需要同步返回支付结果,这就要求当前系统必然要有异步转同步的操作。异步转同步必然要引入超时的概念,因为客户端不能无限期的等待。客户端异步发出一个请求,但是希望在指定时间内获得结果,这个结果可以是支付结果,可以是异常结果,也可以是超时结果。这个结果的返回不依赖服务端的存在而存在,换句话说,即使服务端挂了,也要能够给客户端一个超时通知。
综上,我们需要一个脱离于业务的应用来完成上述的功能,能够在分布式多系统之间进行超时管理。本文以数据表乐观锁的方式来控制多个系统的锁竞争关系。

二、表结构

完成本系统需要两个领域的表,一个是控制分布式锁的表,简称X表,用来记录锁版本号;一个是超时控制表,简称Y表,用来记录客户端注册的超时时间、客户端来源、业务表主键,状态信息。Y表如下:

使用一个sql筛选出过期的数据:
select sourceid,seqid from Y where exptime< sysdate and status='0'
根据sourceid系统可以定位客户端来源,使用jms选择器特性,可以将这个超时信息发送给指定的客户端。可以参照我的这篇博文:
http://51think.net/article/23

三、实现逻辑

实现逻辑从代码层面分析。我们可以在系统中写一个while循环,单线程执行:

trylock方法就是上文所述的获取乐观锁。方法体内部也是一个while循环,如果获取不到锁,就休眠60秒,然后继续尝试获取锁。

这一行是获取锁的逻辑,用内存里的版本号与数据表X表中的版本号进行对比,如果一致,则认为获取到锁,然后将数据库和内存的版本号都+1。如果不一致,则将数据库的版本号同步到内存中,等待(60秒)下一次重新获取锁。

以B系统注册全局超时为例,超时时间为60秒,当下游系统在60秒内没有给予响应,超时系统会将超时响应返回给B系统,B系统可以根据当前的数据状态来判断是否需要回滚,并包装错误信息返回给前端。