思想:前端 限流:页面静态化处理、防止用户重复点击、秒杀接口地址隐藏、数学公式校验
后端 限流:信号量限流、漏桶、令牌桶算法
核心:保证库存安全,不会发生超卖
实现方式:redis+mysql (简单实现,如果分布式系统可以加消息队列),redis 里面存商品id 库存,因为库存要频繁读取。
第一种 加锁
能保证库存安全,缺点:锁等待的时间太长了,锁的颗粒度太大
优化方式:秒杀和入库分开写,降低锁的颗粒度,入库用乐观锁控制 (如果不加锁会出现多减的情况)
吞吐量
优化前:
优化后:
第二种 :redis incr decr
redis 原子操作天然幂等
例 set 商品id 100
吞吐量
乐观锁优化:
传统方式:
select version , goods from items where id=100;
insert into (id,item_id) order (null,100);
update items set goods=goods-1,version=version+1 where id=100 and version=#{version};
优化后
商品库存扣减时,尤其是在秒杀、聚划算这种高并发的场景下,若采用version号作为乐观锁,则每次只有一个事务能更新成功,业务感知上就是大量操作失败
select goods from items where id=100;
insert into (id,item_id) order (null,100);
update items set goods=goods-1 where id=100 and goods-1>0;
没错!你参加过的天猫、淘宝秒杀、聚划算,跑的就是这条SQL,通过挑选乐观锁,可以减小锁力度,从而提升吞吐~
总结:
保证超卖基本上可以这样做,如果是分布式的话,可以用 redlock,来保证redis 里面预设库存安全,要求在严格点可以用etcd 的锁,etcd 用 raft 保证一致性