秒杀项目
1. 商品列表页,用户浏览商品
2. 点击进入某个商品的详情页
3. 进入商品详情页后
• 秒杀未开始显示秒杀倒计时
• 秒杀已开始显示秒杀按钮
• 秒杀已结束显示秒杀结束
4. 用户在商品详情页点击秒杀按钮后
① 验证商品id和秒杀唯一标志是否合法 (秒杀唯一标识:暴露秒杀地址)
② 判断秒杀时间是否开始
判断商品的秒杀开始时间和结束时间,用当前系统时间和他们做比较
③ 判断秒杀是否抢光了
判断Redis中该商品的库存>0可以秒杀,<=0秒杀结束
④ 判断用户是否已经秒杀过该商品
判断Redis中的key是否存在,用户秒杀后会在Redis中设置一个占位的key来标识用户已经秒杀过该商品
5. 判断当前系统流量是否已经超过阈值
• 通过Redis的List数据结构实现
• 每有一个用户请求,就将用户的请求放入List
• 当List的长度达到我们设置的最大值后(通常设置为商品库存数的100倍等)
• 拒绝后续用户的访问,减轻系统的压力
• 用户秒杀流程执行结束后,不管是秒杀成功还是失败,都需要将限流的List弹出一个元素,以便于让后面的人可以再进来一个
7. 进行秒杀
① 减库存
在redis中减库存,采用redis减库存 decrBy 方法(单线程的操作,不会产生数据冲突)
我们数据库中并没有直接减库存,因为数据库性能瓶颈问题
最终我们采用定时任务每隔几秒同步一次Redis库存到数据库,让数据库的库存和redis的库存同步
② 下订单
• 异步下订单,也是为了避免直接操作数据库
• 采用队列ActiveMQ下订单
• 减库存成功后,给MQ发一个消息
• 消息监听器接收到消息后在数据库创建订单
• 如果消息消费不过来,可以设置concurrency="8" 8个消费者,那么消费消息的速度就会加快,不会产生消息的堆积
③ 告知前台页面秒杀结果
创建订单成功或者失败后,都把秒杀结果放入到redis中;
前台页面采用ajax轮询方式查询redis获取最终秒杀结果,给用户提示。