栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

订单超时 取消订单 的几种实现方案总结与对比

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

订单超时 取消订单 的几种实现方案总结与对比

开场白:老铁们对于文章有错误、不准确,或需要补充的请留言讨论 ,大家共同学习。如果觉得还不错的请关注、留言、点赞 、收藏。 创作不易,且看且珍惜

场景 :

在开发中,往往会遇到一些关于延时任务的需求。例如:生成订单 30 分钟未支付,则自动取消;生成订单 60 秒后,给用户发短信。

方案

此处就涉及到 延时任务 和 定时任务 等问题。
这里只说 方案 思路 和 优缺点,代码不做实现。

序号方案思路优点缺点
1quartz(定时任务 轮询)用quartz 定时去扫描订单 查询过期简单 快捷 易行,业务小的可以考虑 支持集群操作(1)对服务器内存消耗大
(2)时效性差,存在延迟,比如你每隔 3 分钟扫描一次,那最坏的延迟时间就是 3 分钟
(3)效率低。假设你的订单有几千万条,每隔几分钟这样扫描一次,数据库损耗极大 (4)可能重复执行。如果第一次轮询耗时长,第二次轮询又开始了,会造成任务重复执行
(5)占用数据库资源,对数据库的压力比较大
2JDK 的延迟队列 (DelayQueue )利用 JDK 自带的 DelayQueue 来实现,这是一个无界阻塞队列,该队列只有在延迟期满的时候才能从中获取元素,放入 DelayQueue 中的对象,是必须实现 Delayed 接口的。效率高,任务触发时间延迟低。(1)服务器重启后,数据全部消失,怕宕机
(2)集群扩展相当麻烦
(3)因为内存条件限制的原因,比如下单未付款的订单数太多,那么很容易就出现 OOM 异常
(4)代码复杂度较高
3redis zset 缓存利用 redis 的 zset,zset 是一个有序集合,每一个元素(member)都关联了一个 score,通过 score 排序来取集合中的值重启或宕机 会丢失数据 (有人会说redis持久化 ,redis最大优点快 ,持久化会降低性能,就算持久化停机、宕机也会丢失一段时间的数据,具体不过多说。)存在一个致命的硬伤,在高并发条件下, 会出现多个线程消费同一个资源的情况
(解决方案:
(1)用分布式锁,但是用分布式锁,性能下降了,该方案不细说。
(2)对 ZREM 的返回值进行判断,只有大于 0 的时候,才消费数据,于是将 consumerDelayMessage() 方法里的:)
4redis键空间机制(Keyspace Notifications)利用该机制可以在 key 失效之后,提供一个回调,实际上是 redis 会给客户端发送一个消息。是需要 redis 版本 2.8 以上。(1)由于使用 Redis 作为消息通道,消息都存储在 Redis 中。如果发送程序或者任务处理程序挂了,重启之后,还有重新处理数据的可能性。
(2)做集群扩展相当方便
(3)时间准确度高
(1)需要额外进行 redis 维护。
(2)Redis的发布/订阅目前是即发即弃(fire and forget)模式的,因此无法实现事件的可靠通知。也就是说,如果发布/订阅的客户端断链之后又重连,则在客户端断链期间的所有事件都丢失了。此方案不是太推荐,当然,如果你对可靠性要求不高,可以使用
5MQ 使用消息队列我们可以采用 RabbitMQ 的延时队列。RabbitMQ 具有以下两个特性,可以实现延迟队列。
(1) RabbitMQ 可以针对 Queue 和 Message 设置 x-message-tt,来控制消息的生存时间,如果超时,则消息变为 dead letter
。(2) lRabbitMQ的 Queue 可以配置 x-dead-letter-exchange 和 x-dead-letter-routing-key(可选)两个参数,用来控制队列内出现了 deadletter,则按照这两个参数重新路由。结合以上两个特性,就可以模拟出延迟消息的功能。
高效,可以利用 rabbitmq 的分布式特性轻易的进行横向扩展,消息支持持久化增加了可靠性本身的易用度要依赖于 rabbitMq 的运维。因为要引用 rabbitMq,所以复杂度和成本变高
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/993028.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号