定时任务高效触发
解决某些有到期时间的场景,不适合定时扫描表来完成处理的情况:
有几个场景业务的处理
一:有一个很大的商品订单表,每天新增数十万条数据。每条数据有个到期时间,需要在到期时间后做一些处理,譬如关闭订单,改变状态之类的。
二:有个付款功能,有到期时间,时间到了需要关闭,或者通知用户等等。
三:抢购时,时间到了,用户不处理不付款的,要把商品回到库存里之类的。
大概类似的一些有到期时间功能的业务场景,但是要么是有较强的实时性,譬如希望到期后立马就改变状态或者做出一些通知之类的,要么是数据量巨大的。
那么可能首先想到的思路就是开个定时任务,隔一段时间去扫一下表,看看到期时间,然后做处理。
很明显,扫表是个很大的工作量,耗时耗资源,甚至会产生死锁什么的。而且大部分时候的扫描是无用的,产生了很多无用的查询。
那么这种问题解决思路
在添加数据时,将ID和过期时间放到redis里,用那个能排序的结构sortSet,或者类似的能记录时间的中间件,做好排序。然后起个后台任务或者新起个项目,专门是扫描这个redis的第一条数据,也就是最快要过期的,这样只需要查询一条就行了,只要第一条不过期,那后面的就不用看了,也就不需要去操作数据库。倘若第一条过期了,就做相应的处理,然后移除掉,再去扫第二条,依次类推。这样查询就很少,也不需要查表。所以可以把扫描间隔设的很短,来达到强实时性。
自己的想法
首先设置一个全局的list集合,添加订单成功后将订单id保存到list集合里,设置非常短的定时任务可以是 1s,取出list 里的第一条,如果满足失效时间,将订单id 发mq消息出去,做一个异步处理比如改订单状态,将list中的第一个数据 remove出去,然后再取出第一条。
有一个问题:定时任务只支持单机 所以双机要加分布式锁