延迟队列的实际使用案例
首先我们需要一个延迟队列provider,这个需要注入一个redisson客户端
@Component
public class DelayedQueueProvider {
private final RedissonClient redissonClient;
// 配置已经自动注入构造完成
public DelayedQueueProvider(RedissonClient redissonClient) {
this.redissonClient = redissonClient;
}
/**
* 添加延迟任务
*
* @param delayedName 延迟名称
* @param val 值
* @param delayTime 延迟时间
* @param timeUnit 时间单位
* @param env 环境信息
*/
public void addDelayedTask(String delayedName, String val, long delayTime, TimeUnit timeUnit, String env) {
final DelayedTaskInfo task = new DelayedTaskInfo();
task.setCreateAt(System.currentTimeMillis());
task.setDelayTime(delayTime);
task.setTimeUnit(timeUnit);
task.setVal(val);
task.setDelayedName(env + "-" + delayedName);
final RDelayedQueue<DelayedTaskInfo> delayedQueue = getDelayedQueue(env + "-" + delayedName);
delayedQueue.offer(task, delayTime, timeUnit);
}
/**
* 获取阻塞deque
*
* @param queueName 队列名称
* @return {@link RBlockingDeque}<{@link DelayedTaskInfo}>
*/
public RBlockingDeque<DelayedTaskInfo> getBlockingDeque(String queueName) {
return redissonClient.getBlockingDeque(queueName, JsonJacksonCodec.INSTANCE);
}
/**
* 获取延迟队列
*
* @param queueName 队列名称
* @return {@link RDelayedQueue}<{@link DelayedTaskInfo}>
*/
private RDelayedQueue<DelayedTaskInfo> getDelayedQueue(String queueName) {
return redissonClient.getDelayedQueue(getBlockingDeque(queueName));
}
}
再写一个任务启动Listener
@RequiredArgsConstructor
@Slf4j
@Component
public class DelayedTaskListener implements ApplicationRunner {
private final DelayedQueueProvider delayedQueueProvider;
@Value("${spring.profiles.active}")
private String env;
@Autowired
private BusinessService businessService;
@Override
public void run(ApplicationArguments args) throws Exception {
delayedTaskHandle(env + "-" + QueueConstant.SWITCH_CONTROL_DELAYED_TASK_QUEUE);
}
public void delayedTaskHandle(String delayedQueueName) {
final Thread thread = new Thread(() -> {
final RBlockingDeque<DelayedTaskInfo> blockingDeque = delayedQueueProvider.getBlockingDeque(delayedQueueName);
while (true) {
try {
//将到期的数据取出来,等待超时0.5s
final DelayedTaskInfo delayedTaskInfo = blockingDeque.poll(500, TimeUnit.MILLISECONDS);
if (Objects.isNull(delayedTaskInfo)) {
continue;
}
log.info("DelayedTask task :[{}]", delayedTaskInfo);
// 这里可以替换成为你们自己的业务,就是把存进去的json转为对象,然后在进行业务处理
//SyncSwitchControlReq req = JsonTool.jsonToObject(delayedTaskInfo.getVal(), SyncSwitchControlReq.class);
//businessService.syncSwitchControl(req);
} catch (Exception e) {
log.error("DelayedTaskListener#delayedTaskHandle error delayedQueueName:[{}]", delayedQueueName, e);
}
}
});
// 设置成为守护线程
thread.setDaemon(true);
thread.start();
}
}
在实际的业务的位置进行使用:需要注入该provider,调用方法addDelayedTask(),我这里的req是我要往队列里放的数据,我是直接存储为json,比较方便
// 往队列里添加任务
delayedQueueProvider.addDelayedTask(
QueueConstant.SWITCH_CONTROL_DELAYED_TASK_QUEUE,
JsonTool.dataToJson(req),
500,
TimeUnit.MILLISECONDS,
env
);
本文来自博客园,作者:程序员鲜豪,转载请注明原文链接:https://www.cnblogs.com/hg-blogs/p/18692629