如何解决超卖等常见问题

高并发

如果需要做一个秒杀系统,最重要的是要解决高并发问题。因为在那一刻肯定有很多顾客过来抢。

秒杀活动一定是高并发的,在那一秒,无数的用户抢购商品,如果我们每个请求过来,都要与数据库进行交互,那么MySQL一定是扛不住的,所以我们的秒杀要基于redis来进行。

Redis单机支撑每秒几万的写入。这样性能不是问题。而且Redis还可以做各种的水平扩展和集群支持。这样,性能就能完全满足我们的秒杀需要。

那么这种情况下,在我们发布秒杀活动的时候,要将我们的商品与库存写入redis。当用户进行抢购的同时,我们直接对redis的库存进行操作,例如扣减。

扣减redis内库存数量后,发送扣减成功的消息到消息队列,由后续的订单服务,支付服务之类的进行处理。最后再由mysql进行库存扣减。

这样的话,比如说一开始,我们有两万个用户来进行秒杀,但我们可能只有十个商品。那么其实最终和mysql进行交互的只有十个商品,大大减轻mysql的压力。那么这种是可以支持高并发的。

解决超卖

超卖的情况指的是如库存只有十个,但是卖了二十个这样的情况。

因为我们已经将库存名额加载到了Redis,那么我们一定要保证精确的计数。如果redis的库存数量错误,就会导致超卖的问题产生。

在秒杀的时候分为两步:

  1. 判断库存名额是否充足。
  2. 减少库存名额,扣减成功就是抢到。

假如说,这两个操作不是原子性,那么在高并发情况下可能就会出现问题。比如,第一步所有的人都过来发现库存名额都充足,然后去全部扣减,那么扣减的数额高于我们redis里面存的。

所以说,我们的关键是保证两种操作的原子性。每一个请求一过来,我们都使用lua脚本来进行支持,先判断库存名额是否充足,然后再进行减少。

一定保证两个请求是原子的,这样就能解决我们的超卖问题。

解决少卖

库存扣减成功,但是实际订单没有生成或者是其他的没有处理好的情况。那么就会引发出少卖问题。

这种情况就是扣减了库存,但是消息没发出,订单生成失败等各种各样的情况,导致我们没有卖成功。

我们扣减库存后,发送消息队列,这里要有重试策略,如果发送消息失败进行重试,超过重试次数后,则要持久化磁盘由补偿服务来进行扫描,进行后续业务处理。类似于mysql的日志持久化。

比如我们配置三次重试,那么就要把消息做一个持久化磁盘的操作,一定要把消息保存起来。

使用保存服务或定时服务等来进行扫描。扫描之后再进行补偿,再进行支付,再进行一个订单的处理,这种情况下就能实现少卖情况的处理。保证我们的用户抢到了,是一定可以正常处理的。

这种持久化的方式类似于mysql的日志持久化,可以类比。

参考资料【大厂面试题】秒杀系统如何解决超卖等常见问题?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值