记一次用户抢购商品导致服务器炸了
回复之前的误解
之前因为没有将 php-fpm
并发配置调高,导致一堆 502
。
后面调高就好了。
一堆瞎操作,原来是没有调整配置….
最后就 60%
cpu
小程序: 狮力健
(现在几乎没什么人了 口罩的高峰期过了)
问题产生
某个商品突然说要做秒杀。
秒杀,挺耗费时间了,老板和客户商量,最后改成抢购。
其实就是增加库存功能,然后人工在固定时间改库存,用户抢购。 (哈哈哈 就是这么简单)
活动规则
昨天 ( 5 - 11)
服务器直接炸了,几十秒之内所有项目不能访问。
出现超卖。
在10号才三十几人,没想到11号,马上变成1.2k人,我丢。
我本以为是个小项目,什么限制都没做。
(经历过太多这种小项目了)
11号10点一到,直接炸了,还超卖。
改善
限制: (都要先经过 redis
的限制)
- 每个人每秒只能访问一次
lpop
保证不超卖
我以为这样不会炸了。
今天 ( 5 - 12 )
又炸了,但是没有超卖,比昨天好很多,还能访问。
(3秒)
残余问题
少卖
用户发起购买请求,库存-1,返回支付参数给前端。 也就是说: 用户不支付,也会库存-1
本来30个名额的,现在卖了30个,只有20个支付了,10个未支付,所以是少卖了。
我不想用复杂的来写
- 老板不会ra我花费太多时间来 客户也没有说什么
- 我怕坑,如果用了队列,还要自己测,测了上线还担心bug
我慢慢想 简单
&& 又能解决的办法
为何不在支付成功后再库存-1 ?
除了抢购商品都是这样处理的
抢购商品这样处理的话 逗我吗 ……
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 4年前 自动加精
高认可度评论:
1、下单减库存。即生成一个订单,库存减1 。这种情况,会出现恶意下单情况,用户只下单,不付款。
2、付款减库存。即订单付完款后才减去相应的库存。这种处理方式不会出现1内的问题,但会出现用户拍下时有货,付款后没货的情况,用户体验极差 :joy:。
如果抢购成功,就直接让其支付。不支付,就视其放弃抢购,然后加回到库存里去。这样可以避免被人恶意占用库存。
实际抢购商品的数量和抢购人数相差很大可以直接在前面随机拒绝掉一大波人
没付款的库存就留明天抢购嘛,都一样的
可以写个定时任务,30分钟之后未付款的库存在加回去
@晓轩 30分钟后可能抢购都结束了,真想抢购的没抢购,抢到的又不付钱,我看限时抢购应该付钱了再减库存。
1、下单减库存。即生成一个订单,库存减1 。这种情况,会出现恶意下单情况,用户只下单,不付款。
2、付款减库存。即订单付完款后才减去相应的库存。这种处理方式不会出现1内的问题,但会出现用户拍下时有货,付款后没货的情况,用户体验极差 :joy:。
@一个人的江湖 所以说多备点货才是最好的解决方法 :joy:
用 redis 单线程不会出现重复问题,同一个地址 ip 手机号都该认为是同一个用户,限制用户,然后客户端可以加个验签,访问做个限制,防止别人跑脚本
5分钟内支付啊,未支付就是放弃资格
下单的时候
@crazy 这个语句是不是会剩最后一个商品谁也拍不走吧
如果抢购成功,就直接让其支付。不支付,就视其放弃抢购,然后加回到库存里去。这样可以避免被人恶意占用库存。
话说没上锁吗,不然怎么会超卖呢,,,
几台服务器?简单描述下架构? :grin:
1、设定一个较短的时间不付款取消订单,如5分钟
2、在用户下单的时候如果库存为0那么一并返回未付款的人数,合并后返回信息如 “商品已售空, 12人未付款, 请休息一下再抢, 还有机会哦~”
付款成功减少库存,商品库存为1的时候,然后n个人同时付款,最后只有一个人购买成购,还要做自动退款处理 :joy:
我们之前遇到过,用秒杀系统容易超卖,后来改成抢优惠券 :sob:
我想到的方案有两种:
注意:建议是返回一个秒杀地址,所带参数使用加密算法进行加密(这样可以防止恶意秒杀)
具体实现:
面试题常考的,让你碰到了。
依稀记得疫情期间我项目抢特价蔬菜一下400份秒空还没有用redis限制,,我的居然没超卖...
实际抢购商品的数量和抢购人数相差很大可以直接在前面随机拒绝掉一大波人
我给出的建议是:
1、少卖问题处理: 用户购买生成订单才库存数-1,并返回支付参数给前端,同时设置订单的有效期在1-5分钟之内,如果时间过了库存数+1,因为秒抢的的商品过了5分钟就不会有人抱有希望,所以把握这个点。
2、优化处理:
nginx 弄炸的,
一样的, 所有的抢购是抢到了就-1, 但是一般都有订单超时自动取消业务的, 你可以使用redis key过期事件来监听订单超时未支付自动取消, 这样把库存加回来
我们一般都是把商品信息, 库存都存到redis中, 这样避免频繁查询mysql, 但是会有很小的概率碰到缓存不一致的问题, 只能隔段时间清次redis, 不知道大家缓存不一致的问题是怎么解决的呢?
【还有3天就不用了,客户没有说必须要改,老板不想改,我不敢改 怕出问题】 老铁在这个公司扮演的是嘛角色 :joy:
既然都用了
redis
就继续用redis
来解决呀。发起付款,减库存。来个超时自动将未付款订单设置为超时。同时释放库存呢。比较好奇服务器的配置是什么?
秒杀系统设计,推荐这篇文章:博客:秒杀系统的设计
淘宝京东都是下单锁库存的,看直播经常有踢人释放库存的。
我有个朋友想知道是哪个小程序做特价,顺便提一句,高并发的业务场景少用io操作,比如你用的:config
和我遇到的情况类似,我是做了时间限制,一分半订单过期不能支付,两分钟后执行定时任务取消该订单,增加库存量
学习小米模式-先预约-在发码-在付款 这样就不会有超卖的情况了。。。码都是预先生成和库存一致的
你都说了小项目了,那就别在乎这点了。。。。
我只想说前东家的公司服务器是16核16G的,数据库是4核16G,抢购直接用LockforUpdate都没事