首页 > 数据库 >Redisson使用延时队列

Redisson使用延时队列

时间:2023-10-12 22:34:05浏览次数:39  
标签:orderId Redisson 队列 任务 延时 blockingDeque

延时队列

在开发中,有时需要使用延时队列。

比如,订单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

相关文章

  • 王道408---DS---线性表、栈、队列与数组
    错题2.21、题目中提到在第i个位置一般是指在下表为i的位置2、线性表元素的序号是从1开始,而在第n+1个位置插入相当于在表尾追加。静态链表树的双亲表示法就是使用了这种思想吧卡特兰数\[\text{}\frac1{n+1}C_{2n}^{n}\]栈的数学性质:n个不同元素进栈,出栈元素不同排列的个......
  • golang之异步队列Asynq
    Asynq[1]是一个Go实现的分布式任务队列和异步处理库,基于redis,类似Ruby的sidekiq[2]和Python的celery[3]。Go生态类似的还有machinery[4]和goworker同时提供一个WebUI asynqmon[5],可以源码形式安装或使用Dockerimage,还可以和Prometheus集成dockerrun--rm--nameasynqmon......
  • TMS刷新后Buffer队列被清空
    前言。。。。。少叙。。。症状按SAP标准配置了传输请求,导入传输请求(addtobuffer),这时在buffer/SID下能看到加入的TR请求但在STMS刷新后,buffer/SID里的文件被刷新,信息显示为 Troubleshooting 。。。。。(凭老司机猜测,你信吗)解决方案测试10有8-9是在同一个传输系统......
  • 数据结构之队列(循环队列)
    循环队列又称为环形队列,有如下4个特点:在循环队列的定义中规定了两个索引指针:front和rear。front指向第一个有效元素的位置,而rear可以理解为用来记录队尾元素的下一个位置。当队列为空时,front==rear;当队列满时,(rear+1)%n=front.这样可以让队列看起来像一个环状......
  • Redis学习之Redisson实现可重入锁
    如何实现可重入锁目的:保证同一个线程可以多次获取同一把锁解决思路:在锁的value中额外保存当前线程获取锁的次数,每次获取锁+1、释放锁-1,当次数为0时才真正删除key。采用hash结构来存储锁信息,如图:流程如下:注意:所有的判断和操作都需要使用Lua脚本来保证原子性每......
  • 利用redis队列抢红包
    /***发放红包*@param$money//金额*@param$num//数量*@param$packet//群组id确保key的唯一性*@param$user_id//发放人*@returnarray*/publicfunctiondeliver($num,$packet,$money,$user_id){//业......
  • 阻塞队列
    什么是阻塞队列阻塞队列是一种特殊的队列,它支持线程安全并发操作的同时提供了阻塞操作功能。在阻塞队列中,当队列为空时,从队列中取元素的操作将被阻塞,而当队列已满时,往队列中放元素的操作也会被阻塞。阻塞队列的应用场景阻塞队列常用于生产者和消费者的场景,生产者是向队列里添加......
  • 分布式锁-实现原理(setnx,redisson)
         ......
  • 07_用队列实现栈
    用队列实现栈【题目】请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop和empty)。对应于leetcode225题实现MyStack类:voidpush(intx)将元素x压入栈顶。intpop()移除并返回栈顶元素。inttop()返回栈顶元素。booleanempty(......
  • 232. 用栈实现队列
    请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):实现 MyQueue 类:voidpush(intx) 将元素x推到队列的末尾intpop() 从队列的开头移除并返回元素intpeek() 返回队列开头的元素booleanempty() 如果队列为空,返回 true ;否则......