整个秒杀的业务步骤
前端传递userId和goodsId参数,以及请求头的token
验证请求头token的合法化, 参数由@Valid验证
判断库存是否为空
判断是否重复抢购
调用service,执行秒杀过程
减少库存,sql语句要stock>0
生成秒杀订单和订单详情
将goodsId作为key, userId作为value 存入redis里的Set中,方便判断重复抢购问题
初步优化 ps: 主要目的:减少和数据库的交互(redis), 将生成订单和秒杀解耦(rabbitMQ)
判断合法化
通过redis里的数据,判断是否重复抢购
判断redis里的存库是否大于0 (Controller 实现 InitializingBean,初始化时放入库存)
调用service,执行秒杀过程
通过redis里提前存好的数据,来预减库存
将消息发送给rabbitMQ,异步生成订单.
将goodsId作为key, userId作为value 存入redis里的Set中,方便判断重复抢购问题
最终优化结果 ps:减少和redis的通信,使用lua脚本,增强高并发的安全性
验证内存标记stockmap是否为空
验证token和参数的合法化
验证redis的库存是否为空
验证redis是否重复购买
使用lua脚本预减redis库存
发送秒杀消息至RabbitMQ
rabiitMQ消费者接受消息
判断消息合法性
调用Service层相关方法
service层中生成订单,
service层中减少库存
service层中将
userId
加入redis的Setgoods:id