版权声明:本文为博主原创文章,未经博主允许不得转载。
以下均为出现在抢购、秒杀的常经理
1、token的作用
token的用法为,用户渲染商品抢购页面时,服务端做一个加密处理,可以考虑为用MD5(户ID + 商品ID + 任意数字(例如用户生日)) .
这个做法的关键是,防批量刷新商品。
例如:
A、一个用户在登录态下,刷所有抢购商品接口。
B、一个用户不同的切换账号,来刷所有抢购商品接口。(如果登录有验证码,此步可以忽略)
2、关于减库存的导致超卖的问题
减库存的操作是比较复杂的,主要利用MySQLinnor db 的update的写锁机制。
update status = 1 where ItemId = xxx and status = 0 limit 1;
并发数的考虑为库存*10,可以用nginx限流。(mysql连接池限流的话,服务端压力会过大,因此建议在上层反向代理限流)
分一下两种情况
A:当抢购商品为1件时
10个用户并发,只有一个用户能在执行这条sql上返回1,其他均为0。因此,返回1 的那个用户为抢购成功的用户,可以继续向下走流程。其他用户返回抢购失败。
B:当抢购商品大于1件时
为了防止多个线程去更新1条数据,行级锁导致大量线程争抢,就是 update num = num -1 这种。
因此,需要把这个商品拆成 N条数据,每条数据的抢购数都为1。(在抢购前,这些数据要提前添加好,等抢购开始时只做状态变更)
第一步,先查出主键(随机返回主键),
a1方法:select 主键 from table_name whereItemId = xxx and status = 0ORDER BY RAND() limit 1;
a2方法:如果你用 ORDER BY RAND() 来随机读取记录的话,当数据表记录达到30万或者更多的时候,mysql将非常吃力. 那么用这种方案:取出所有主键,代码中ramdom随机取出一个。
第二部,update status = 1 where 主键 = xxx and status = 0。
这样,多个线程争抢与库存值相等的数据 的情况下,就会减少等待时间。