Redisson延迟队列 您所在的位置:网站首页 redission延时队列原理 Redisson延迟队列

Redisson延迟队列

2024-03-29 13:53| 来源: 网络整理| 查看: 265

场景: 需求:

支付的二维码,超过两个小时以后,如果还未支付,则自动转为取消支付,或者支付超时的状态

需求分析:

1,动态定时任务:

每个支付的二维码创建的时候,创建一个动态的定时任务,两个小时候自动执行,更新支付状态,可以解决这个问题。

(1)持久化:

如果服务重启了,动态定时任务会丢失,导致部分数据没办法更新状态。

(2)分布式:

如果当服务重启时,自动扫描数据,重新计算时间,再次创建动态定时任务。可以解决(1)的问题,但是当分布式,多个节点的时候,都会重新加载所有的任务,这样性能上不是最优解,只能在数据源上加上节点名称,不同的服务节点,加载属于自己的定时任务,可以解决这个问题。总的想想,太麻烦了,还是算了。

2,Redisson延迟队列

(1)持久化:队列信息放在Redis上,服务重启不影响。

(2)分布式:多节点去Redis拿去数据,谁抢到算谁的,不会存在同一个任务,多个节点支持。唯一不足就是过度依赖Redis,万一Redis崩了,那就凉凉了(那就是要把Redis配置高可用,当前业务就不用管了)。总体来说还是比较好用的。

实现

1,创建延迟队列的监听任务【RedisDelayedQueueListener】,消费延迟队列

2,创建新增延迟队列的类,用于创建延迟队列

3,整体初始化,把监听任务与spring绑定,扫描各个监听延迟队列的实现类,并开启单独线程,监听任务。

4,创建延迟任务(开始测试使用)

连接Redis

不贴代码了,自己在网上搜

监听延迟队列

接口:

/** * 队列事件监听接口,需要实现这个方法 * * @module * @author frank * @date 2021/8/19 10:50 */ public interface RedisDelayedQueueListener { /** * 执行方法 * * @param t */ void invoke(T t); }

实现:

import com.sxmaps.netschool.common.redisson.RedisDelayedQueueListener; import com.sxmaps.netschool.service.vo.school.SchoolAccountPayStateReqVO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * 支付二维码监听器 * * @module * @author frank * @date 2021/8/19 10:49 */ @Component public class PayQCordListener implements RedisDelayedQueueListener { private final Logger logger = LoggerFactory.getLogger(PayQCordListener.class); @Autowired private SchoolAccountService schoolAccountService; @Override public void invoke(SchoolAccountPayStateReqVO payStateReqVO) { logger.info("支付二维码-延迟失效,内容:{}", payStateReqVO); //处理业务,更新二维码状态 logger.info("支付二维码-延迟失效,内容:{},处理结果:{}", payStateReqVO,respDTO); } } 增加延迟队列 import org.redisson.api.RBlockingQueue; import org.redisson.api.RDelayedQueue; import org.redisson.api.RedissonClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; /** * 增加延迟信息 * * @author frank * @module * @date 2021/8/19 10:49 */ @Component public class RedisDelayedQueue { private final Logger logger = LoggerFactory.getLogger(RedisDelayedQueue.class); @Autowired RedissonClient redissonClient; /** * 添加队列 * * @param t DTO传输类 * @param delay 时间数量 * @param timeUnit 时间单位 * @param 泛型 */ private void addQueue(T t, long delay, TimeUnit timeUnit, String queueName) { logger.info("添加延迟队列,监听名称:{},时间:{},时间单位:{},内容:{}" , queueName, delay, timeUnit,t); RBlockingQueue blockingFairQueue = redissonClient.getBlockingQueue(queueName); RDelayedQueue delayedQueue = redissonClient.getDelayedQueue(blockingFairQueue); delayedQueue.offer(t, delay, timeUnit); } /** * 添加队列-秒 * * @param t DTO传输类 * @param delay 时间数量 * @param 泛型 */ public void addQueueSeconds(T t, long delay, Class


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有