首页 简历|笔试面试

订单30分钟未支付则自动取消,该怎么实现?

  • 25年9月4日 发布
  • 110.86KB 共5页
订单30分钟未支付则自动取消,该怎么实现?订单30分钟未支付则自动取消,该怎么实现?订单30分钟未支付则自动取消,该怎么实现?订单30分钟未支付则自动取消,该怎么实现?订单30分钟未支付则自动取消,该怎么实现?

订单 30 分钟未支付则自动取消,该怎么实现?

崭新的办公室,崭新的会议室,窗明几净,地毯一尘不染,这样舒适的工作环境,小二不

由得期待了起来,要是这次面试能通过,我一定要好好干!

小二敲敲门,蹑手蹑脚进入了办公室,态度虔诚,弯腰鞠躬,面露微笑,寒暄过后,一切

就绪,面试官老王问了这么一个问题。

“看你简历上写对电商购物比较熟悉,那在下单之后,通常会有一个倒计时,如果超过支

付时间,订单就会被自动取消。”

1756714456487-b01bd521-e1a6-47b2-a92a-aaf37f497d03.webp

“你就来说说,你们项目中,订单超时未支付自动取消都用了哪几种方案?”

听完老王这句话,小二心里狂喜,前几天才在二哥公众号看到这道面试题,这就碰上了!

但小二依然表现出非常淡定的态度,娓娓道来。。。。。

以下是小二之前看到的解决方案,他可以说是倒背如流。

1.定时任务

这是最容易想到的办法,定时任务去轮询数据库,取消即将超时的订单。

1756714456508-0717fd25-8e45-40cd-a7a9-fb405dceead0.webp

定时任务实现方式有很多种,大概可以分为两类:<font style="color:rgb(53, 179,

120);background-color:rgba(27, 31, 35, 0.05);">本地定时任务</font>和<font

style="color:rgb(53, 179, 120);background-color:rgba(27, 31, 35, 0.05);">分布式定

时任务</font>。

1756714456569-6796b2fd-ba26-423f-aa45-0fe09fca39bc.webp

本地定时任务,适用于单机版的业务系统,实现方式非常多样:

• 永动机线程:开启一个线程,通过 sleep 去完成定时,一些开源中间件的某些定时任

务是通过这种方式实现的。

• JDK Timer:JDK 提供了 Timer API,也提供了很多周期性的方法。

• 延迟线程池:JDK 还提供了延迟线程池 ScheduledExecutorService,API 和 Timer 类

似。

• Spring Task:Sprig 框架也提供了一些定时任务的实现,使用起来更加简单。

• Quartz:Quartz 框架更进一步,提供了可以动态配置的线程池。

分布式定时任务:适用于分布式的业务系统,主要的实现框架有两种:

• xxl-job:大众点评的许雪里开源的,一款基于 MySQL 的轻量级分布式定时任务框

架。

• elastic-job:当当开发的弹性分布式任务调度系统,功能很强大,相对重一些。

定时任务实现的优点是开发起来比较简单,但是它也有一些缺点:

• 对数据库的压力很大,定时任务造成人为的波峰,执行的时刻数据库的压力会陡增

• 计时不准,定时任务做不到非常精确的时间控制,比如半小时订单过期,但是定时任

务很难卡准这个点

2.被动取消

在文章开头的那个倒计时器,大家觉得是怎么做的呢?一般是客户端计时+服务端检查。

什么意思呢?就是这个倒计时由客户端去做,但是客户端定时去服务端检查,修正倒计时

的时间。

那么,这个订单超时自动取消,也可以由客户端去做:

• 用户留在收银台的时候,客户端倒计时+主动查询订单状态,服务端每次都去检查一

下订单是否超时、剩余时间

• 用户每次进入订单相关的页面,查询订单的时候,服务端也检查一下订单是否超时

1756714456496-c045981d-7a96-4aa2-bc01-731663c48072.webp

这种方式实现起来也比较简单,但是它也有缺点:

• 依赖客户端,如果客户端不发起请求,订单可能永远没法过期,一直占用库存

当然,也可以<font style="color:rgb(53, 179, 120);background-color:rgba(27, 31,

35, 0.05);">被动取消</font>+<font style="color:rgb(53, 179, 120);background-

color:rgba(27, 31, 35, 0.05);">定时任务</font>,通过定时任务去做兜底的操作。

3.延时消息

第三种方案,就是利用延时消息了,可以使用 RocketMQ、RabbitMQ、Kafka 的延时消

息,消息发送后,有一定延时才会投递。

1756714456405-89822fc5-2194-4722-a4d0-b29f5bbce613.png

我们用的就是这种,消息队列采用的是 RocketMQ,其实 RocketMQ 延时也是利用定时任

务实现的。

使用延时消息的优点是比较高效、好扩展,缺点是引入了新的技术组件,增加了复杂度。

4.其他方案

除了上面的三种,其实还有一些其它的方式,例如本地延迟队列、时间轮算法、Redis 过

期监听……

但是我觉得,应该不会有人真考虑过在生产上使用这些方法。

后记:

时光飞逝,转眼就来到了 2023 年 03 月 09 日,这已经是小二入职新公司的第二个年头,

公司熬过了去年的寒冬后,就像如今的天气一下,春暖花开,一切重回正轨,蒸蒸日上了

起来。小二的学习劲头也更足了些:“今年,我一定要更上一层楼才好呢!”

二哥总结的背诵版答案。

第一种,可以直接使用定时任务轮询数据库,比如说 Spring Task,或者 xxl-job,或者

quartz,都可以。

检查并取消 30 分钟内未支付的订单。这种方法的优点是实现简单,但缺点是数据库压力

大,并且扫描的时候要检查一遍所有订单。

第二种,用户停留在收银台时,显示倒计时并主动查询订单状态,服务端检查订单是否超

时。

这种方法的优点是实现简单,缺点是依赖客户端行为,可能会导致订单无法及时过期。

第三种,利用消息队列的延时消息功能,RocketMQ 或者 Kafka 都可以。订单生成的时候

发送一个 30 分钟后过期的消息,消息过期时出发订单取消操作。

这种方法的优点是高效,缺点是需要引入新的技术组件。

我通常会采用延时消息的方案,同时结合定时任务进行兜底,确保订单能够被及时取消。

开通会员 本次下载免费

所有资料全部免费下载! 推荐用户付费下载获取返佣积分! 积分可以兑换商品!
一键复制 下载文档 联系客服