数据库|领导:谁再用 Redis 实现过期订单关闭,立马滚蛋!!

数据库|领导:谁再用 Redis 实现过期订单关闭,立马滚蛋!!

文章图片

数据库|领导:谁再用 Redis 实现过期订单关闭,立马滚蛋!!

文章图片

数据库|领导:谁再用 Redis 实现过期订单关闭,立马滚蛋!!

文章图片

数据库|领导:谁再用 Redis 实现过期订单关闭,立马滚蛋!!

文章图片


\">
由于Redis具有过期监听的功能 , 于是就有人拿它来实现过期订单关闭 , 但是这个方案并不完美 。 今天来聊聊11种实现订单定时关闭的方案 , 总有一种适合你!
在电商、支付等系统中 , 一般都是先创建订单(支付单) , 再给用户一定的时间进行支付 , 如果没有按时支付的话 , 就需要把之前的订单(支付单)取消掉 。
这种类似的场景有很多 , 还有比如到期自动收货、超时自动退款、下单后自动发送短信等等都是类似的业务问题 。
本文就从这样的业务问题出发 , 探讨一下都有哪些技术方案 , 这些方案的实现细节 , 以及相关的优缺点都有什么?
因为本文要讲的内容比较多 , 涉及到11种具体方案 , 受篇幅限制 , 这篇文章主要是讲方案 , 不会涉及到具体的代码实现 。 因为只要方案搞清楚了 , 代码实现不是难事儿 。
一、被动关闭在解决这类问题的时候 , 有一种比较简单的方式 , 那就是通过业务上的被动方式来进行关单操作 。
简单点说 , 就是订单创建好了之后 。 我们系统上不做主动关单 , 什么时候用户来访问这个订单了 , 再去判断时间是不是超过了过期时间 , 如果过了时间那就进行关单操作 , 然后再提示用户 。

这种做法是最简单的 , 基本不需要开发定时关闭的功能 , 但是他的缺点也很明显 , 那就是如果用户一直不来查看这个订单 , 那么就会有很多脏数据冗余在数据库中一直无法被关单 。
还有一个缺点 , 那就是需要在用户的查询过程中进行写的操作 , 一般写操作都会比读操作耗时更长 , 而且有失败的可能 , 一旦关单失败了 , 就会导致系统处理起来比较复杂 。
所以 , 这种方案只适合于自己学习的时候用 , 任何商业网站中都不建议使用这种方案来实现订单关闭的功能 。
二、定时任务定时任务关闭订单 , 这是很容易想到的一种方案 。
具体实现细节就是我们通过一些调度平台来实现定时执行任务 , 任务就是去扫描所有到期的订单 , 然后执行关单动作 。

这个方案的优点也是比较简单 , 实现起来很容易 , 基于Timer、ScheduledThreadPoolExecutor、或者像xxl-job这类调度框架都能实现 , 但是有以下几个问题:
1、时间不精准 。 一般定时任务基于固定的频率、按照时间定时执行的 , 那么就可能会发生很多订单已经到了超时时间 , 但是定时任务的调度时间还没到 , 那么就会导致这些订单的实际关闭时间要比应该关闭的时间晚一些 。
2、无法处理大订单量 。 定时任务的方式是会把本来比较分散的关闭时间集中到任务调度的那一段时间 , 如果订单量比较大的话 , 那么就可能导致任务执行时间很长 , 整个任务的时间越长 , 订单被扫描到时间可能就很晚 , 那么就会导致关闭时间更晚 。
3、对数据库造成压力 。 定时任务集中扫表 , 这会使得数据库IO在短时间内被大量占用和消耗 , 如果没有做好隔离 , 并且业务量比较大的话 , 就可能会影响到线上的正常业务 。
4、分库分表问题 。 订单系统 , 一旦订单量大就可能会考虑分库分表 , 在分库分表中进行全表扫描 , 这是一个极不推荐的方案 。