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

1、场景描述如下

服务器重启后,延迟队列take数据阻塞,不执行,必须等到下一个内容offer时,队列才会把阻塞的消息全部处理掉

2、解决方案

初始化程序时,再次调用延时队列的 getDelayedQueue方法

RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);

 

3、伪代码如下

offer元素到延时队列
  @RequestMapping("/test")
    public String test() {
        RBlockingQueue<String> blockingQueue = redissonClient.getBlockingQueue("RDelayedQueue");
        RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);
        delayedQueue.offer("11", 10, TimeUnit.SECONDS);
        delayedQueue.offer("22", 20, TimeUnit.SECONDS);
        delayedQueue.offer("33", 30, TimeUnit.SECONDS);
        delayedQueue.offer("100", 300, TimeUnit.SECONDS);
        return "test";
    }

 

程序运行后,开启新的线程从延时队列获取元素

package com.ahies.stm.app.init;

import com.ahies.stm.app.centerControl.control.queueHandler.TestDelayedQueueHandler;
import com.ahies.stm.app.centerControl.control.queueHandler.VisitBehaviorQueueHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Description
 * @Date 2019/12/9 20:30
 * @Author zsj
 * 实现CommandLineRunner  接口 程序启动后执行
 * 开启一个线程 交给线程池执行
 */

@Component
@Order(5)
public class TestDelayedQueueRunner implements CommandLineRunner {

    public static ExecutorService queueThreadPool = Executors.newFixedThreadPool(1);
    @Autowired
    TestDelayedQueueHandler testDelayedQueueHandler;


    @Override
    public void run(String... args) throws Exception {
        queueThreadPool.execute(testDelayedQueueHandler);

    }
}

 

线程类,从延时队列获取元素

package com.ahies.stm.app.centerControl.control.queueHandler;

import com.ahies.stm.app.bigdata.visitorBehavior.entity.VisitBehavior;
import com.ahies.stm.app.bigdata.visitorBehavior.service.VisitBehaviorService;
import com.ahies.stm.app.centerControl.equipment.entity.ControlEquipment;
import com.ahies.stm.app.centerControl.equipment.service.ControlEquipmentService;
import com.ahies.stm.app.centerControl.object.entity.ControlObject;
import com.ahies.stm.app.centerControl.object.service.ControlObjectService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.Getter;
import lombok.Setter;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Description TODO
 * @Date 2019/12/9 20:32
 * @Author zsj
 */
@Getter
@Setter
@Component
public class TestDelayedQueueHandler implements Runnable {
    @Autowired
    RedissonClient redissonClient;

    @Override
    public void run() {
        RBlockingQueue<String> blockingQueue = redissonClient.getBlockingDeque("RDelayedQueue");
        //下面两行 必不可少 防止出现 服务器重启后,
        // 延迟队列take数据阻塞,不执行,必须等到下一个内容offer时,队列才会把阻塞的消息全部处理掉
        RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);
        delayedQueue.offer("xx", 1, TimeUnit.SECONDS);
        while (true) {
            try {
                String data = blockingQueue.take();
                System.out.println(data);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章