解決服務器重啓後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();
            }
        }

    }
}

 

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