一、基本概念
什么是延时队列?首先它要具有队列的特性,再给它附加一个延迟消费队列消息的功能,延迟队列相对比普通队列,区别就在延时的特性上,普通队列先进先出,按入队顺序进行处理,而延时队列中的元素在入队时会指定一个延时时间,希望能够在指定时间到了以后处理。
二、使用场景
业务类场景:
1、支付订单成功后,指定时间以后将支付结果通知给接入方。
2、淘宝订单业务:下单之后如果三十分钟之内没有付款就自动取消订单。
3、美团或饿了吧订餐通知:下单成功后60s之后给用户发送短信通知。
4、会议预定系统,在预定会议开始前半小时通知所有预定该会议的用户。
5、IT问题工单超过24小时未处理,则自动拉企微群提醒相关责任人。
6、用户下单外卖以后,距离超时时间还有10分钟时提醒外卖小哥即将超时。
技术框架场景∶
1、关闭空闲连接。服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之。
2、缓存。缓存中的对象,超过了空闲时间,需要从缓存中移出。
3、任务超时处理。在网络协议滑动窗口请求应答式交互时,处理超时未响应的请求等。
上面的这些场景都可以通过延时队列解决。
三、实现方案
1、定时任务轮询数据库
2、Java提供的DelayQueue
3、netty提供的时间轮算法实现类HashedWheelTimer
4、消息中间件(rabbitmq、rocketmq.kafka)延迟消息
5、redis的sorted set或redis key过期回调
四、实现落地
1)、定时任务轮询数据库
采用定时任务实现延迟,对业务表进行轮询判断,订单到点执行,有一点点误差。实现如下:1)使用单机版的spring sceduled+分布式锁,代码如下:
@Slf4j
@Configuration
@EnableScheduling
public class OrderAutoCancelSpringJob {
@Resource
private DistributeLockHelper distributeLockHelper;
private static final String ORDER_AUTO_CANCEL_LOCK = "orderAutoCancelLocScheduled(cron = "0/