自用,分布式的延时队列
效果

前提代码
XML
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.23.5</version>
</dependency>
XML
spring:
data:
redis:
host: localhost
password: 123456
java
@Getter
@ToString
public class DelayedTask<T> implements Delayed, Serializable {
private static final long serialVersionUID = 3018458065076640934L;
private final T taskContent;
private final Long triggerTime;
/**
* @param seconds 秒
*/
public DelayedTask(T taskContent, Long seconds) {
this.taskContent = taskContent;
this.triggerTime = System.currentTimeMillis() + seconds * 1000;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(triggerTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
return this.triggerTime.compareTo(((DelayedTask) o).triggerTime);
}
}
核心代码
java
@RestController
@RequiredArgsConstructor
@RequestMapping("/")
@Slf4j
public class DelayController {
private final RedissonClient redissonClient;
private volatile boolean QUEUE_RUNNING = true;
@GetMapping("/test")
public void test() throws InterruptedException {
RBlockingDeque<DelayedTask> blockingDeque = redissonClient.getBlockingDeque("my-delay-queue");
RDelayedQueue<DelayedTask> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
new Thread(()->{
while (QUEUE_RUNNING){
try {
var delayedTask = blockingDeque.take();
log.info("需要执行这个任务,{}", delayedTask);
} catch (Exception e) {
log.error("延时任务出错:{}", e);
}
}
}).start();
Thread.sleep(15000L);
QUEUE_RUNNING = false;
}
@PostMapping("/add")
public void add() {
RBlockingDeque<DelayedTask> blockingDeque = redissonClient.getBlockingDeque("my-delay-queue");
final RDelayedQueue<DelayedTask> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
delayedQueue.offer(new DelayedTask("做这个任务", 3L),3L, TimeUnit.SECONDS);
delayedQueue.offer(new DelayedTask("做这个任务2",5L),5L, TimeUnit.SECONDS);
delayedQueue.offer(new DelayedTask("做这个任务3",8L),8L, TimeUnit.SECONDS);
}
}
我自己的踩坑
1.如果延时队列,发现延时时间没有效果,请注意一下你的自定义对象,有没有实现序列化接口?
2.如果实现了序列化接口,还是发现没有延时 ,那么请记住这个问题。然后把自定义的类直接换成String,把自定义的对象转换成JSON去存,不要纠结,这个真的很浪费时间。后续再排查。