历史潮流浩浩荡荡,顺之者昌,逆之则亡。——孙中山

基于延迟队列打造精准的订单超时关闭

JAVA编程 徐 承恩 33℃ 0评论

订单的超时取消很多系统采用定时任务,实际上达不到要求。我用的是延迟队列,但缺点是只实现了基于jvm的,分布式采用的是修改之前去查询订单状态,以及分布式锁获取的方式来控制,这样获得锁的,先去查订单是否已经取消掉,如果没有,就改成去掉。但这种方式虽然效果不错,我对这个半吊子的思路还是不满意的,后面有时间再优化一些,做成分布式的。

整个功能实际就是利用延迟队列的特性。延迟队列有个时间属性,一旦到达这个时间节点,会立即从队列中弹出任务,这时候,轮询守护线程就可以执行这个任务了。如果没有到达这个时间节点,无论轮询守护线程怎么轮询,都查不到对应的任务弹出。从jdk1.5开始,java就提供了Delayed接口,用于延迟队列。该接口是继承于Comparable<T>的。至于延迟队列里的任务是什么样子,则由自己定义,我为了便于多线程跑,使用了继承了Runnable的任务,所以定义成这个样子。

执行流程:

  1. 系统启动,初始化延迟队列。随即会启动守护线程,用于轮询延迟队列里的任务到期弹出。
  2. 将现有数据库中处于待支付状态的订单插入延迟队列。
  3. 一旦有新的订单加入,则放入延迟队列中。
  4. 一旦有任务到期,则守护线程会接到弹出的任务,并执行该任务。
  5. 该任务会从更新数据库中的订单状态。
  6. 一旦有用户取消订单/支付订单,则从延迟队列中查询到该订单的延迟任务,手动删除该任务。

这个是使用的spring boot的线程池的,所以需要配置一个线程池。

延迟队列代码:

延迟队列中放置的任务:

延迟队列的管理类,有轮询守护线程:

在系统初始化的时候,需要将数据库中已经处于等待超时状态的订单打入延迟队列:

如果用户取消订单/中间执行支付操作后,则从延迟队列中去掉任务:

如果用户中间下单,则加入延迟队列:

工具类:

转载请注明:徐叔科技 » 基于延迟队列打造精准的订单超时关闭

喜欢 (1)
发表我的评论
取消评论
表情

嗨,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址