延时队列
在开发中,有时需要使用延时队列。
比如,订单15分钟内未支付自动取消。
jdk延时队列
如果使用 jdk自带的延时队列,那么服务器挂了或者重启时,延时队列里的数据就会失效,可用性比较差。
Redisson延时队列
可以使用Redisson的延时队列。
Redisson的配置,详情见:https://blog.csdn.net/sinat_32502451/article/details/133799192
在延时队列中添加任务
public void addDelayQueue(String orderId) {
RBlockingDeque<String> blockingDeque = redissonClient.getBlockingDeque("orderQueue");
RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
//在延时队列中添加任务,5秒后生效
delayedQueue.offer(orderId, 5, TimeUnit.SECONDS);
log.info("addDelayQueue orderId:" + orderId);
}
取出延时队列中的任务
取出延时队列中的任务,如果延时队列中没有任务,会阻塞,直到队列中添加了任务。
public void takeDelayQueue() {
log.info("DelayQueue take start.");
RBlockingDeque<String> blockingDeque = redissonClient.getBlockingDeque("orderQueue");
RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
while (true) {
String orderId = null;
try {
//取出延时队列中的任务,如果延时队列中没有任务,会阻塞,直到队列中添加了任务。
orderId = blockingDeque.take();
} catch (Exception e) {
log.error("blockingDeque.take error.", e);
}
if (orderId != null) {
log.info("DelayQueue get orderId:" + orderId);
//实际情况不需要break,此处为了方便调试
break;
}
}
}
日志:
调用 takeDelayQueue()方法,不断在延时队列中拉取数据,由于队列中没有数据,所以会先阻塞。
接着调用 addDelayQueue()方法,往队列中添加数据,观察日志,可以发现 5秒后,取到队列中的数据。
[2023-10-12 21:30:49.536] INFO c.c.m.c.controller.DelayQueueController [line: 63] DelayQueue take start.
[2023-10-12 21:30:54.725] INFO c.c.m.c.controller.DelayQueueController [line: 54] addDelayQueue orderId:12345
[2023-10-12 21:30:59.821] INFO c.c.m.c.controller.DelayQueueController [line: 72] DelayQueue get orderId:12345
参考资料:
https://blog.csdn.net/sinat_32502451/article/details/133799192
标签:orderId,Redisson,队列,任务,延时,blockingDeque From: https://www.cnblogs.com/expiator/p/17760768.html