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();
}
}
}
}