未付款订单占用库存的MQ实现方案

作者: 刘一二 发布时间: 2022年7月21日 浏览: 1331

用户下完订单到支付完成期间,需要锁定库存防止超卖,如何不依赖数据库,实现较高负载呢?

常见的方案是频繁的读取数据库中的订单,统计总库存占用,检查是否付款超时。如果系统的负载量较高,这种方案很快将数据库的CPU占用达到极限,系统响应速度迅速下隆。

我在一个项目中应用了消息队列(RabbitMQ)的方案实现的这个需求,分享一下。

简化流程:

flow.png

下单时,第一步要操作的,就是遍历订单里的商品列表,将商品数量累加到 Redis 库存占用上,防止超卖。

在商品详情页,展示的 商品可用库存 = 商品库存 - 库存占用

第二步操作,将订单写入MQ队列,因为订单是按时间顺序写入队列的,所以最先失效的订单一定是队首的订单。因此,计划任务只需要循环检查队首的订单

  • 如果订单付款时间未超时,假如还有 50 秒,则休眠 50 秒后继续处理。
  • 如果订单已到达超时时间,则检醒订单原始状态
  • 如果订单原始状态已非未付款(如已付款,已取消),则将订单移出队列,处理下一单
  • 如果订单原始状态仍为未付款,则释放库存占用

注意,取消订单操作需要主动释放库存占用

计划任务内流程:

task-flow.png

在我们的项目中,有一种特殊 VIP 的用户,他们的未付款超时时间长达12小时(普通用户半小时),他们常用这种方式免费锁定库存,我们暂不关注这种需求的合理性,系统如何实现呢?

在MQ中加一条队列即可,半小时超时的一个队列,12小时超时的一个队列

最新文章
热门文章
导航