秒杀项目思路整理

1、商品预热

因为秒杀的商品需要存入Redis中,所以需要提前将商品信息存入Redis,而不是初次有用户访问时在去查Redis。
思路:当项目启动时,执行查询秒杀信息业务。这里用到了 @PostConstruct注解,其是随着Servlet生命周期进行的。参考文章1

    @PostConstruct
    public void init() throws Exception {
        ResultGeekQ<List<GoodsVo>> goodsListR = goodsService.goodsVoList();
        if (!ResultGeekQ.isSuccess(goodsListR)) {
            log.error("***系统初始化商品预热失败***");
            return;
        }
        List<GoodsVo> goodsList = goodsListR.getData();
        for (GoodsVo goods : goodsList) {
            redisService.set(GoodsKey.getMiaoshaGoodsStock, "" + goods.getId(), goods.getStockCount());
        }

2.用户信息

用户登录存Redis,有效期12分钟

3.商品详情页

每次查询返回秒杀状态:未开始,正在进行,已结束
#TODO缓存HTML

4.秒杀业务

点击秒杀按钮后,会执行以下业务:
1.验证秒杀验证码正确与否
2.生成随机UUID,用MD5加密,存入Redis作为秒杀Path(过期时间60s),并返回
3.前台携带该path继续请求confirm接口,
3.1 后台校验该用户path是否与redis中相等
3.2 CurrentHashMap存储商品销售完的标记,查询map中是否存在对应商品标记,存在返回商品已售完,不存在,继续向下执行。
3.3 设置排队标记,过期时间根据业务定,存入Redis,如果redis已经存在key则设置成功,不存在key则设置失败,返回正在排队中
3.4 校验时间,防止刷时间:再次验证系统当前时间是否在秒杀时间范围内
3.5 查询数据库订单信息,判断当前用户是否秒杀到商品,若已经秒杀到,提示不能重复秒杀,为秒杀到,向下继续进行。
3.6 扣减库存:修改redis对应key的商品数。
①通过jedis.decr(realKey),返回扣减完剩余商品数,如果返回<0,代表卖超了,需要增加回原来库存数,也就是jedis.incr(realKey),增加为0.并存储商品售完CurrentHashMap中
ZK修改标记 #TODO
3.7 发送消息队列,创建订单消息,在catch中捕获AmqpException(消息队列)异常,则让库存加1,移除售空map中对应商品标记,让其他用户继续秒杀该商品。也要ZK修改标记 #TODO
3.8 消息队列监听:
①再次查询库存是否有剩余,没有,返回;,有继续执行
②再次判断该用户是否已经秒杀到,不允许重复秒杀。
③减库存(MySQL),下订单,SQL加判断,防止变为负数

   update miaosha_goods set stock_count = stock_count - 1
       where goods_id = #{goodsId} and stock_count > 0

订单表中加唯一索引,防止用户重复购买
在这里插入图片描述
这里主要是异步下单,先预减Redis库存,然后再修改MySQL。
④创建订单,并返回。

原创文章 63 获赞 48 访问量 8万+

猜你喜欢

转载自blog.csdn.net/csp_6666/article/details/106095908