定时关闭场景全分析:
推荐使用 方案
定时任务(对于时间精度要求不高,单体应用)
被动关闭(不推荐)
delayqueue(jdk内部,无法持久化,不推荐)
netty时间轮(基于内存,无法持久化,不推荐)
kafka rabbitmq 死信队列,插件 rocketmq 延迟队列( 不推荐, mq方案不支持,大量无效调度)
redis 过期监听 (不推荐,容易丢消息) zset (不推荐,消息重复消费)
reddison(推荐可以用)
实现复杂度上:
ressison> rabbitmq插件》 rabbitmq死信队列 》 rocketmq 延迟队列 > redis 的zset >
redis过期监听 =kafka时间轮》 定时任务》 netty时间轮》jdk delayqueue >被动关闭
不同场景
单体: 业务量不大:netty时间轮, jdk delayqueue 定时任务
分布式应用:业务量不大 redis过期监听,rabbitmq死信队列,redis的zset,定时任务
分布式应用:业务量大,并发高 redisson rabbitmq插件 kafka时间轮 rocketmq 延迟消息 定时任务
业务量特别大:定时任务
考虑到方案完整,复杂度,还是推荐使用三方框架,比较建议 定时任务,redisson+redis,rabbitmq插件 rocketmq 延迟消息 等方案。
但考虑到订单到期关闭特别,订单量特别大,mq并不适合
扩展
netty时间轮
在Netty中,实现一个时间轮(Time Wheel)通常用于实现定时任务。时间轮是一种高效的数据结构,用于在固定频率下触发事件。它通过将时间分割成多个槽(slot),每个槽代表一个固定长度的未来时间点,从而减少了对定时器的频繁操作,提高了效率。
如何在Netty中使用时间轮
Netty本身并没有直接提供时间轮的实现,但是你可以使用HashedWheelTimer,它是Netty中一个基于时间轮的实现,用于调度定时任务。
步骤 1: 添加依赖
首先,确保你的项目中包含了Netty的依赖。如果你使用Maven,可以在pom.xml中添加如下依赖:
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timeout;
import io.netty.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class TimeWheelExample {
public static void main(String[] args) {
// 创建一个HashedWheelTimer实例
HashedWheelTimer timer = new HashedWheelTimer();
// 定义一个定时任务TimerTask task = new TimerTask() {@Overridepublic void run(Timeout timeout) throws Exception {System.out.println("任务执行: " + System.currentTimeMillis());}};// 安排任务在5秒后执行,每隔2秒执行一次timer.newTimeout(task, 5, TimeUnit.SECONDS);timer.newTimeout(task, 2, TimeUnit.SECONDS); // 这里演示了如何再次安排任务(例如,重新触发)// 注意:实际应用中,你可能需要某种方式来停止timer,例如使用shutdownGracefully()方法。// timer.stop(); // 停止计时器(在实际应用中可能需要)
}
}