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