前言
实现延迟队列的方式有很多种,有本地自己jdk方式实现、Quartz 定时任务实现、RabbitMQ 延时队列实现,还有Redis方式实现。综合自己的生产情况,Redis是符合分布式服务及开发成本较小的一种方式。基本的机制如下图
本文将通过工具包Redisson用极简单的方式来实现一个延迟队列。同时提供一下比较完备的例子。
延迟队列的使用场景
背景:
1、当订单一直处于未支付状态时,如何及时地关闭订单
2、如何定期检查处于退款状态的订单是否已经退款成功
3、在订单长时间没有收到下游系统的状态通知的时候,如何实现阶梯式的同步订单状态的策略
4、在系统通知上游系统支付成功终态时,上游系统返回通知失败,如何进行异步通知实行分频率发送:15s 3m 10m 30m 30m 1h 2h 6h 15h
一般的解决方案
1、最简单的方式,定时扫表。例如对于订单支付失效要求比较高的,每2S扫表一次检查过期的订单进行主动关单操作。优点是简单,缺点是每分钟全局扫表,浪费资源,如果遇到表数据订单量即将过期的订单量很大,会造成关单延迟。
2、使用RabbitMq或者其他MQ改造实现延迟队列,优点是,开源,现成的稳定的实现方案,缺点是:MQ是一个消息中间件,如果团队技术栈本来就有MQ,那还好,如果不是,那为了延迟队列而去部署一套MQ成本有点大
3、使用Redis的zset、list的特性,我们可以利用redis来实现一个延迟队列RedisDelayQueue。本文使用Redisson来实现。
Redisson实现方式
- 添加包
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.5</version>
</dependency>
- 实现
下面用一个抢红包的例子来演示实现过程。在一定时间内,红包没有领取的话,将失效。
创建红包类