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