大家在之前的项目中是否遇到过这样的场景:
- 1.下订单后,30分钟不支付,需要自动把订单关闭。
- 2.用户订阅某商品的抢购提醒,在商品开始抢购前5分钟,系统给用户推送商品马上开始抢购的信息。
从上面这些场景,我们可以看到,在我们生成一个任务后,任务并没有马上执行,而是要等到设定的时间后才执行。比如订单关闭的任务需要在创建订单后的30分钟才执行,提醒用户的任务需要在商品开卖前5分钟才执行。我们把这种类型的任务叫做延迟任务。
处理延迟任务有很多种方法。在这里我们介绍一种使用redis的有序集合的方法。
有序集合
我们知道有序集合可以根据score的大小来排序,那么我们就可以把使用时间戳作为score,命令作为member存入有序集合,然后启动一个守护进程,读取当前时间之前的集合数据,并且执行其中的命令。 具体可看下面的流程图:

具体使用的命令如下:
-
- 使用ZADD添加任务 "ZADD 队列名称 时间戳 任务"。
-
- 在守护进程中使用 "ZRANGEBYSCORE 队列名称 0 时间戳 LIMIT offset count"。
-
- 任务执行完成后使用 "ZREM 队列名称 任务" 来删除任务。