文章目录
背景
生成订单后一段时间不支付订单需要自动关闭
解决方案
定时任务轮询关单
设置定时任务轮询关闭
缺点:每个订单的创建时间不一样,定时任务的规则无法设定,如果将定时任务执行的间隔设置的过短,太影响效率;
“懒”关单
在用户进入订单界面时,判断时间再关单。
缺点:用户进入订单时间不定,会影响那些依赖订单关闭状态后续业务操作,比如 关单后需要发短信通知用户订单关闭,需要上报数据;而且要是用户不再进入,订单就无法关闭。
Redis发布订阅机制-监听Redis key过期事件关单
在生成订单时,向 Redis 中增加一个 KV 键值对,K 为订单号,保证通过 K 能定位到数据库中的某个订单即可,V 可为任意值。
假设,生成订单时向 Redis 中存放 K 为订单号,V 也为订单号的键值对,并设置过期时间为 30 分钟,如果该键值对在 30 分钟过期后能够发送给程序一个通知,或者执行一个方法,那么即可解决订单关闭问题。
实现:通过监听 Redis 提供的过期队列来实现,监听过期队列后,如果 Redis 中某一个 KV 键值对过期了,那么将向监听者发送消息,监听者可以获取到该键值对的 K,注意,是获取不到 V 的,因为已经过期了,这就是上面所提到的,为什么要保证能通过 K 来定位到订单,而 V 为任意值即可。拿到 K 后,通过 K 定位订单,并判断其状态,如果是未支付,更新为关闭,或者取消状态即可。
缺点:
- 引入Redis,复杂度上升;
- Redis 目前的订阅与发布功能采取的是发送即忘(fire and forget)策略, 所以如果程序需要可靠事件通知(reliable notification of events), 那么目前的键空间通知可能并不适合:当订阅事件的客户端断线时, 它会丢失所有在断线期间分发给它的事件,并不能确保消息送达。