16 基于MQ实现秒杀订单系统的异步化架构以及精准扣减库存的技术方案

1.秒杀场景下的抢购流程分析

(1)商品页面问题

在秒杀活动当晚,有大量用户(可能多大几十万甚至上百万)会集中登录到APP上,然后同时访问这个秒杀活动的商品页面,这个频繁访问商品页面的问题已经被商品技术团队解决掉了

(2)订单系统与数据库压力问题

在抢购开始时,商品按钮从灰色不可用变成可点击状态。然后瞬间可能几十万甚至上百万人会同时点击这个按钮,尝试对后台发起请求去抢购这个商品。

在这个过程中,和往常购买商品一样,比如下订单、支付、扣减库存以及后续一系列事情。如果按照之前的策略,让所有请求都访问到订单系统以及订单数据库,那么不可避免的是导致订单系统和数据库压力过大。

这是亟待解决的问题。

3.用答题的方法避免作弊抢购以及延缓下单

问题:这里考虑到,有人会自己写一个抢购的脚本或者作弊软件,疯狂的发送请求去抢商品。

解决办法:在用户参与抢购前,让他点击按钮之后先进行答题,也就是先弹出来一个框,让他回答一个问题,回答正确了他才能发起抢购的请求。

这样有以下两个好处:

  1. 避免了一些作弊软件去发抢购请求
  2. 不同人的答题速度不一样,可以把答题人发送请求的时间错开,不会在一个时间点发起请求

4.独立的秒杀活动订单系统

秒杀活动的商品品类是有限的,如果让秒杀下单请求和普通下单请求都由一套订单系统来承载,那么可能会导致秒杀下单请求耗尽了订单系统的资源,或者导致系统不稳定,然后导致其他普通下单请求也出现问题,没有办法完成的下单。这里进行分流

采用对订单系统部署两个集群,一个集群是秒杀订单系统集群,一个集群是普通订单系统集群。

5.基于Redis实现下单时精准扣减库存

秒杀活动中,大量请求进入订单系统调用库存系统的接口,然后直接访问库存数据库去扣减,那么势必导致瞬时压力过大,可能让库存系统的压力很大。

解决方案,将每个秒杀商品的库存提前写入Redis中,然后当请求到来之后,就直接对Redis中的库存进行扣减。

Redis可以轻松用单机扛住每秒几万高并发。假设有一万件商品秒杀,那么前一万个请求可以成功从Redis中扣减库存,抢购到该商品。后续的请求在Redis进行扣减时发现库存已经没了,就无法抢购到商品了。

6.抢购完毕之后提前过滤无效请求

当Redis中的库存被扣减完之后,后续的请求也就不需要发送到秒杀系统中了。

这里直接可以在商品抢购完毕之后,在Zookeeper中写入一个秒杀完毕的标志位,然后ZK会反向通知Nginx中我们写的Lua脚本,通过Lua脚本后续再请求过来的时候直接过滤掉,不要向后转发了。从而最大幅度削减对后端秒杀系统的请求压力。

7.瞬时高并发下单请求进入RocketMQ进行削峰

场景:一万件商品同时被一万人秒杀成功,会导致瞬间上万请求访问到订单数据库中创建订单。此时对数据库的压力就会很大。

方案:引入RocketMQ进行削峰处理。

每个请求进来在Redis中秒杀库存成功,就认为需要生成订单,此时发送一个消息到RocketMQ中去。

然后让普通订单系统从RocketMQ中消费秒杀成功的消息进行处理。对于MQ来说,这种上万的消息积压很容易就扛下来了,只要过了高峰期,订单系统很快就能消费、处理完。这个过程中不会对订单数据库造成过大的压力。

8. 秒杀架构的核心要点

  1. 在前端/客户端设置秒杀答题,错开大量人下单的时间,组织作弊器刷单
  2. 独立出来一套秒杀系统,专门负责处理秒杀请求
  3. 优先基于Redis进行高并发的库存扣减,一旦库存扣完则秒杀结束
  4. 秒杀结束之后,Nginx层过滤掉无效的请求,大幅度削减转发到后端的流量
  5. 瞬时生成的大量下单请求直接进入RocketMQ进行削峰,订单系统慢慢拉取消息完成下单操作

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值