所以 , 定时任务的方案 , 适合于对时间精确度要求不高、并且业务量不是很大的场景中 。 如果对时间精度要求比较高 , 并且业务量很大的话 , 这种方案不适用 。
三、JDK自带的延迟队列有这样一种方案 , 他不需要借助任何外部的资源 , 直接基于应用自身就能实现 , 那就是基于JDK自带的DelayQueue来实现
基于延迟队列 , 是可以实现订单的延迟关闭的 , 首先 , 在用户创建订单的时候 , 把订单加入到DelayQueue中 , 然后 , 还需要一个常驻任务不断的从队列中取出那些到了超时时间的订单 , 然后在把他们进行关单 , 之后再从队列中删除掉 。
DelayQueue是一个无界的BlockingQueue , 用于放置实现了Delayed接口的对象 , 其中的对象只能在其到期时才能从队列中取走 。
这个方案需要有一个线程 , 不断
使用DelayQueue实现超时关单的方案 , 实现起来简单 , 不须要依赖第三方的框架和类库 , JDK原生就支持了 。
当然这个方案也不是没有缺点的 , 首先 , 基于DelayQueue的话 , 需要把订单放进去 , 那如果订单量太大的话 , 可能会导致OOM的问题;另外 , DelayQueue是基于JVM内存的 , 一旦机器重启了 , 里面的数据就都没有了 。 虽然我们可以配合数据库的持久化一起使用 。 而且现在很多应用都是集群部署的 , 那么集群中多个实例上的多个DelayQueue如何配合是一个很大的问题 。
所以 , 基于JDK的DelayQueue方案只适合在单机场景、并且数据量不大的场景中使用 , 如果涉及到分布式场景 , 那还是不建议使用 。
四、Netty的时间轮还有一种方式 , 和上面我们提到的JDK自带的DelayQueue类似的方式 , 那就是基于时间轮实现 。
为什么要有时间轮呢?主要是因为DelayQueue插入和删除操作的平均时间复杂度——O(nlog(n)) , 虽然已经挺好的了 , 但是时间轮的方案可以将插入和删除操作的时间复杂度都降为O(1) 。
时间轮可以理解为一种环形结构 , 像钟表一样被分为多个 slot 。 每个 slot 代表一个时间段 , 每个 slot 中可以存放多个任务 , 使用的是链表结构保存该时间段到期的所有任务 。 时间轮通过一个时针随着时间一个个 slot 转动 , 并执行 slot 中的所有到期任务 。
基于Netty的HashedWheelTimer可以帮助我们快速的实现一个时间轮 , 这种方式和DelayQueue类似 , 缺点都是基于内存、集群扩展麻烦、内存有限制等等 。
但是他相比DelayQueue的话 , 效率更高一些 , 任务触发的延迟更低 。 代码实现上面也更加精简 。
所以 , 基于Netty的时间轮方案比基于JDK的DelayQueue效率更高 , 实现起来更简单 , 但是同样的 , 只适合在单机场景、并且数据量不大的场景中使用 , 如果涉及到分布式场景 , 那还是不建议使用 。
五、Kafka的时间轮既然基于Netty的时间轮存在一些问题 , 那么有没有其他的时间轮的实现呢?
还真有的 , 那就是Kafka的时间轮 , Kafka内部有很多延时性的操作 , 如延时生产 , 延时拉取 , 延时数据删除等 , 这些延时功能由内部的延时操作管理器来做专门的处理 , 其底层是采用时间轮实现的 。
【数据库|领导:谁再用 Redis 实现过期订单关闭,立马滚蛋!!】#而且 , 为了解决有一些时间跨度大的延时任务 , Kafka 还引入了层级时间轮 , 能更好控制时间粒度 , 可以应对更加复杂的定时任务处理场景;
- 微信|微信上有这几个习惯的人,不管是谁都别深交
- OPPO|盘点2022年最热门的两款安卓智能手表,OPPO|华为你选谁?
- 这年头谁还没有一两副耳机?不论平时喜欢听歌|南卡runnerpro4耳机怎么样?
- 3D打印|体验看齐Apple Watch S8的两款安卓手表,OPPO华为你选谁?
- 数据库|亲身体验尼康尼克尔Z 100-400mm F4.5-5.6 VR S
- 小米科技|4K档华为、三星、OPPO主打手机混战,到底谁更值?
- 联想|PC平板二合一的标杆!联想小新Duet和华硕无畏360谁更适合你?
- 谁的胜利:“周杰伦保卫战”中的粉丝们
- 谁上前线?她们说,我的孩子!
- 史前怪物大作战,当棘龙遇上霸王龙,谁输谁赢?