订单超时-延时任务处理

1、定时任务

时效性差,会有一定的延迟,这个延迟时间最大就是每隔一定时间的大小,如果你设置每分钟定时轮询一次,那么理论上订单取消时间的最大误差就有一分钟,当然也可能更大,比如一分钟之内有大量数据,但是一分钟没处理完,那么下一分钟的就会顺延。效率低。对数据库的压力比较大。

2、被动取消

这种方式依赖于用户的查询操作触发,这也就是说如果用户不进行查询订单的操作,该订单就永远不会被取消。不会取消的订单,也就可能意味着库存可能被占用,也可以是被动取消 +定时任务的这种组合实现方式。这种情况下定时任务的时间可以设置的稍微“长“一点。

缺点:
会产生额外影响,比如统计,订单数,库存等产生影响。
影响用户体验,用户打开订单列表可能要处理大量数据,影响显示的实时性。

3.延时消息

针对时间轮算法或者说延时消息,目前有很多消息队列都支持,
比如 RocketMQ,RabbitMQ

  • 死信队列: TTL消息的存活时间、DLX即死信交换机
  • 时间轮:

12:00:00 时启动定时器。 插入任务「12:41:00」时,处理为 c(环数) = (12:41:00 - 12:00:00)/60 - 0 = 41,k(slot key) = (12:41:00 - 12:00:00)%60 - 0= 0;
每一个执行周期到对应的 slot 时,该 slot 对应的链表中所有节点剩余轮数-1 执行到 12:19:01 时,时间轮情况如下:

在这里插入图片描述
一个1天的定时器,时间轮分为3个,小时轮(24 slot)、分钟轮(60 slot)、秒轮(60 slot) 方便理解
在这里插入图片描述

4、延时队列

DelayQueue必须实现 Delayed 接口的

  • JDK 中提供了一组实现延迟队列的API,位于Java.util.concurrent包下DelayQueue

  • DelayQueue是一个BlockingQueue(无界阻塞)队列,

  • 它本质就是封装了一个PriorityQueue(优先队列),PriorityQueue内部使用完全二叉堆来实现队列元素排序。

  • 在向DelayQueue队列中添加元素时,会给元素一个Delay(延迟时间)作为排序条件,队列中最小的元素会优先放在队首。

  • 队列中的元素只有到了Delay时间才允许从队列中取出。

  • 队列中可以放基本数据类型或自定义实体类,在存放基本数据类型时,优先队列中元素默认升序排列,自定义实体类就需要我们根据类属性值比较计算了。

5、Redis 缓存

zset是一个有序集合,每一个元素(member)都关联了一个 score,通过 score 排序来取集合中的值。我们将订单超时时间戳与订单号分别设置为 score 和 member。系统扫描第一个元素判断是否超时。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值