秒杀抢购系统的实现

一、秒杀系统介绍及遇到的挑战

1. 什么是秒杀?

秒杀是网络卖家发布一些超低价格的商品,所有买家在同一时间网上抢购的一种销售方式。由于价格比价低廉,一上架就被抢购一空,有时只需要几秒钟,所以非常考验系统的并发能力。当然,秒杀常见形式有1元秒杀、低价限量秒杀(小米限量秒杀,12306分段限量秒杀)、低价限时限量秒杀(电商平台偏多)。

2. 秒杀业务分析

1.正常电子商务流程
(1)查询商品;(2)创建订单;(3)扣减库存;(4)更新订单;(5)付款;(6)卖家发货
2.秒杀业务特性流程
(1)低廉价格;(2)大幅推广;(3)瞬时售空;(4)一般是定时上架;(5)时间短、瞬时并发量高;
3.秒杀实现技术挑战
(1)秒杀技术挑战
假设某网站秒杀活动只推出一件商品,预计会吸引1万人参加活动,也就说最大并发请求数是10000,秒杀系统需要面对的技术挑战有:后面将谈到的前端层面和业务层面的问题
(2)对现有网站业务造成冲击
秒杀活动只是网站营销的一个附加活动,这个活动具有时间短,并发访问量大的特点,如果和网站原有应用部署在一起,必然会对现有业务造成冲击,稍有不慎可能导致整个网站瘫疾。
解决方案:将秒杀系统独立部署,甚至使用独立域名,使其与网站完全隔离。

秒杀系统架构图:
在这里插入图片描述

3. 秒杀抢购实现遇到的问题

  • 前端层面:
    1.突然增加的网络及服务器带宽
    2.防止用户重复提交
  • 业务层面:
    1.如何防止商品超卖问题
    2.服务器单台机器承受不了
    3.如何限制用户操作频率
    4.如何防止用户作弊行为
    注:秒杀本质也属于高并发优化方案
  1. 为什么秒杀服务需要单独独立以微服务形式部署?
    因为微服务之间互不影响,宕机不至于影响其他服务;当并发量超出预期,Docker部署快速扩容;
  2. 当修改商品库存的请求增多,数据库访问压力增大,如何解决?
    分库分表,r/w分离;
    使用MQ异步修改库存; - - - 这两种治标不治本
    使用令牌桶+MQ异步修改库存 ;- - -推荐方案
  3. 如何防止库存超卖问题?
    使用数据库乐观锁(CAS锁,此种方式有个问题如:100库存100用户抢购,最终只有60个用户秒杀成功,原因是当未获取CAS锁时,当前请求失效,自旋则无此问题,其实秒杀用户很多,最终也会全部秒杀成功);
    使用Redis实现分布式锁;
    使用令牌桶+MQ异步形式实现修改库存(有一个用户等待过程)
  4. 如何限制用户的操作频率?
    使用Redis的SETNX命令,key为用户phone,并指定key过期时间,如10s

二、秒杀系统的实现

1. 秒杀页面前端优化方案(CDN内容分发)

  1. 在一个网站中,大部分的服务器请求带宽资源都被静态资源占用了,静态资源包含(CSS/IMG/JS/MP4)等,而Http协议接口占用带宽资源非常小。
  2. 想让用户的请求及时的发送到服务器端上,服务器带宽一定足够,所以这时候网站一定要实现动静分离架构模式,将静态资源与动态资源分开,静态资源放入到CDN服务器端上。
    1M宽带等于多少Kbps?等于128KB/S,如果加载一个网页含静态资源需要640/KB,那么就需要5秒时间加载整个网页。
    静态资源优化方案
    1.is/css/img实现压缩减少带宽的传输、将静态资源放入第三方资源服务器中(七牛云、阿里OSS)等。
    2.商品详情页面使用Nginx实现缓存,Lua+OpenResty实现商品详情页面的更新;也可以使用时间戳参数更新Nginx静态资源缓存。
  3. 提交后按钮disabled,禁止用户重复提交
    思路:可以给页面表单提前生成隐藏域参数,用户提交表单后台根据该参数判断该表单是否已经提交。

2. 基于MQ+库存令牌桶实现异步修改库存

秒杀抢购修改库存如何减少数据库IO操作:

场景:在高并发情况下,如果突然有10万个不同用户的请求进行秒杀,但是商品的库存数量只有100个,那么这时候可能会出现10万个请求执行修改秒杀库存sql语句,这时候可能会出现数据库访问压力承受不了?

解决方案:读写分离,分库分表,Redis缓存库存等…但是这些方案都是治标不治本,不管秒杀是否成功,每个请求都会对数据库做读写操作,造成数据库压力增大。

最终解决方案

提前生成100(库存数量)个令牌,用户获取到令牌才能执行修改库存的sql语句。

  1. 提前生成100个令牌,获取到令牌后则将商品id和phone投递到消息队列中,消息确认机制保证消息投递成功,消费者进行库存-1和秒杀订单生成,并返回正在排队中…,倒计时几秒后提示消费成功、消费失败、排队中..., 若还是排队中, 前端Ajax根据phone和商品id轮询查询是否秒杀成功。
  2. 没获取到令牌的则提示"宝贝已抢光" 或查询该用户秒杀的商品是否有未付款订单,若有则返回 “有用户拍下未付款,超时将自动释放库存,您还有机会!”。
  3. 订单支付时间内超时的则释放令牌,库存+1,其他用户可继续获取令牌参与秒杀。
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值