秒杀活动
内容
实现简单的秒杀页面(显示当前秒杀活动状态)和秒杀接口,不需要考虑下订单和退货流程。
秒杀接口要求
时间到了才能开始秒杀
不能超买:1个用户只能秒杀1次
不能超卖
在缓存崩溃重启的情况也不能出现超买和超卖的情况
测试
功能正常
1个用户发起100个并发测试
随机用户(userId:rand(1, 1000000000)) 请求,100个并发秒杀,最先完成秒杀1000个商品的活动
数据表结构如下
--
-- 用户秒杀成功记录 `log`
--
CREATE TABLE `log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`eventId` int(11) NOT NULL COMMENT '活动ID',
`userId` int(11) NOT NULL COMMENT '用户ID',
`createTime` int(11) NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `eventId` (`eventId`,`userId`)
) ENGINE=InnoDB AUTO_INCREMENT=4353 DEFAULT CHARSET=utf8;
--
-- 秒杀活动 `event`
--
CREATE TABLE `event` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cnt` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '总量',
`remainCnt` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '剩余数量',
`startTime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '开始时间',
`createTime` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='活动';
实现思路:
1.被动缓存商品库存——redis读取库存,不存在则从数据库内读取活动数据,并缓存库存信息
2.对用户加锁以避免重复抢购,设置过期时间
3.用户加锁成功,再查该用户的购买记录,验证
4.利用redis的decr扣库存,返回接口<0,则操作失败,表明库存已耗尽
5.mysql减库存并记录日志,注意减库存操作加上验证条件remainCnt>0,已避免redis崩溃穿透导致超卖
代码:https://github.com/Alexchent/interview/tree/master/codehero2
网友评论