解决服务器重启后Redisson的delayQueue take数据会阻塞

本文讨论了在使用Redisson实现延迟队列时遇到的问题,即由于未正确初始化延迟队列导致无法接收数据。正确的做法是在类的构造函数中或通过@Bean注解初始化。文中还介绍了RedissonDelayedQueue的内部机制,包括如何定期检查并处理已到期的延迟任务。了解这些细节对于确保延迟队列的正常工作至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要原因是有些人的代码是按照下面这种写法,最主要造成的原因这个写法并不能给你初始化延迟队列,没有初始化延迟队列,就不会接收到延迟队列的数据。

public void addDelay(Object o) {
        RBlockingQueue<CallDTO> blockingFairQueue = redissonClient.getBlockingQueue("delay_queue_call");
        RDelayedQueue<CallDTO> delayedQueue = redissonClient.getDelayedQueue(blockingFairQueue);
        delayedQueue.offer(o, 5, TimeUnit.SECONDS);
    }

正确的写法是 这个代码应该放在另外的地方,要不就是在对应的类的构造函数里面进行初始化,要不就通过@bean的方式注入到容器中,也是初始化。

 RBlockingQueue<CallDTO> blockingFairQueue = redissonClient.getBlockingQueue("delay_queue_call");
 RDelayedQueue<CallDTO> delayedQueue = redissonClient.getDelayedQueue(blockingFairQueue);

源码-稍微写一下大概的思路,具体的可以自己去看源码:
在org.redisson.RedissonDelayedQueue#RedissonDelayedQueue里面有一个初始化任务,这个任务就是查询已经到时间的zset的元素,丢到阻塞队列表面去, 在下面的一行代码里面。

        queueTransferService.schedule(queueName, task);

在下面的这个方法里面启动的。

 public void start() {
        RTopic schedulerTopic = getTopic();
        // 这要是这个地方,监听到状态的变更会执行初始化任务
        statusListenerId = schedulerTopic.addListener(new BaseStatusListener() {
            @Override
            public void onSubscribe(String channel) {
                pushTask();
            }
        });
        
        // 这里是监听到新的延迟队列任务的时候会执行任务。
        messageListenerId = schedulerTopic.addListener(Long.class, new MessageListener<Long>() {
            @Override
            public void onMessage(CharSequence channel, Long startTime) {
                scheduleTask(startTime);
            }
        });
    }
    
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值