面试官:说说电商系统订单超时自动取消怎么实现?你有几种方案?
大家对电商购物应该都比较熟悉了,我们应该注意到,在下单之后,通常会有一个倒计时,如果超过支付时间,订单就会被自动取消。
下单
今天,我们来聊聊订单超时未支付自动取消的几种方案。
1.定时任务
这是最容易想到的办法,定时任务去轮询数据库,取消即将超时的订单。
订单轮询
定时任务实现方式有很多种,大概可以分为两类:本地定时任务和分布式定时任务。
定时任务实现
本地定时任务,适用于单机版的业务系统,实现方式非常多样:
永动机线程:开启一个线程,通过 sleep 去完成定时,一些开源中间件的某些定时任务是通过这种方式实现的。
JDK Timer:JDK 提供了 Timer API,也提供了很多周期性的方法。
延迟线程池:JDK 还提供了延迟线程池 ScheduledExecutorService,API 和 Timer 类似。
Spring Task:Sprig 框架也提供了一些定时任务的实现,使用起来更加简单。
Quartz:Quartz 框架更进一步,提供了可以动态配置的线程池。
分布式定时任务:适用于分布式的业务系统,主要的实现框架有两种:
xxl-job:大众点评的许雪里开源的,一款基于 MySQL 的轻量级分布式定时任务框架。
elastic-job:当当开发的弹性分布式任务调度系统,功能很强大,相对重一些。
定时任务实现的优点是开发起来比较简单,但是它也有一些缺点:
对数据库的压力很大,定时任务造成人为的波峰,执行的时刻数据库的压力会陡增
计时不准,定时任务做不到非常精确的时间控制,比如半小时订单过期,但是定时任务很难卡准这个点
2.被动取消
在文章开头的那个倒计时器,大家觉得是怎么做的呢?一般是客户端计时+服务端检查。
什么意思呢?就是这个倒计时由客户端去做,但是客户端定时去服务端检查,修正倒计时的时间。
那么,这个订单超时自动取消,也可以由客户端去做:
用户留在收银台的时候,客户端倒计时+主动查询订单状态,服务端每次都去检查一下订单是否超时、剩余时间
用户每次进入订单相关的页面,查询订单的时候,服务端也检查一下订单是否超时
被动取消
这种方式实现起来也比较简单,但是它也有缺点:
依赖客户端,如果客户端不发起请求,订单可能永远没法过期,一直占用库存
当然,也可以被动取消+定时任务,通过定时任务去做兜底的操作。
3.延时消息
第三种方案,就是利用延时消息了,可以使用 RocketMQ、RabbitMQ、Kafka 的延时消息,消息发送后,有一定延时才会投递。
延时消息
我们用的就是这种,消息队列采用的是 RocketMQ,其实 RocketMQ 延时也是利用定时任务实现的。
使用延时消息的优点是比较高效、好扩展,缺点是引入了新的技术组件,增加了复杂度。
除了上面的三种,其实还有一些其它的方式,例如本地延迟队列、时间轮算法、Redis 过期监听……
但是我觉得,应该不会有人真考虑过在生产上使用这些方法。
这里再给大家提个小问题,假如我们接入了一种支付方式,支付的周期非常长,我们需要延长订单的有效时间,这种情况下,大家会怎么实现订单超时未支付自动取消呢?
原文:https://mp.weixin.qq.com/s/-Mftl5UFcfA_VR8ZDLE09g
如果感觉本文对你有帮助,点赞关注支持一下,想要了解更多 Java 后端,大数据,算法领域最新资讯可以关注我公众号【架构师老毕】私信 666 还可获取更多 Java 后端,大数据,算法 PDF+大厂最新面试题整理+视频精讲
评论