美文网首页
秒杀接口优化

秒杀接口优化

作者: totohui | 来源:发表于2018-04-30 16:48 被阅读0次

    秒杀接口优化

    1. 系统初始化,把商品库存数量加载到Redis

    MiaoshaController实现InitializingBean

    public void afterPropertiesSet() throws Exception {

        List goodsList = goodsService.listGoodsVo();

        if (goodsList == null) {

            return;

        }

        for (GoodsVo goods : goodsList) {               redisService.set(GoodsKey.getMiaoshaGoodsStock, "" + goods.getId(),     goods.getStockCount()); localOverMap.put(goods.getId(), false);

        }

    }

    2.收到请求,Redis预减库存,库存不足,直接返回,否则进入3

    先判断是否是重复秒杀,然后预减库存,如果库存数量小于0,返回秒杀结束;

    否则请求入队

    @ResponseBody

    public Result miaosha(Model model, MiaoshaUser user, @RequestParam("goodsId") long goodsId) {

        model.addAttribute("user", user);

        if (user == null) {

            return Result.error(CodeMsg.SESSION_ERROR); } // 判断是否重复秒杀

        }

        MiaoshaOrder order =  orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);

        if (order != null) {

            return Result.error(CodeMsg.REPEATE_MIAOSHA); } // 内存标记,减少redis访问

        }

         boolean over = localOverMap.get(goodsId);

        if (over) {

            return Result.error(CodeMsg.MIAO_SHA_OVER);

        }

        // 预减库存

        long stock = redisService.decr(GoodsKey.getMiaoshaGoodsStock, "" + goodsId);// 10

        if (stock < 0) {

            localOverMap.put(goodsId, true);

            return Result.error(CodeMsg.MIAO_SHA_OVER);

        }

        // 入队

        MiaoshaMessage mm = new MiaoshaMessage();

        mm.setUser(user);

        mm.setGoodsId(goodsId); sender.sendMiaoshaMessage(mm);

        return      Result.success(0);// 排队中

    }

    3.请求入队,立即返回排队中

    4.请求出队,生成订单,减少库存

    出队后,先判断商品库存是否小于等于0,是否是重复订单,调用miaoshaService.miaosha(user, goods);//减库存,下订单

    @Transactional public OrderInfo miaosha(MiaoshaUser user, GoodsVo goods) {

    //减库存 下订单 写入秒杀订单

    boolean success = goodsService.reduceStock(goods);

    if(success) { //order_info maiosha_order

        return orderService.createOrder(user, goods); }

    else {

        setGoodsOver(goods.getId());

        return null;

    }

    }

    setGoodsOver就是用redis标记该商品已经卖完了。

    OrderService.createOrder(MiaoshaUser user, GoodsVo goods)

    OrderInfo orderInfo = new OrderInfo();

    ...

    orderDao.insert(orderInfo);

    MiaoshaOrder miaoshaOrder = new MiaoshaOrder(); miaoshaOrder.setGoodsId(goods.getId()); miaoshaOrder.setOrderId(orderInfo.getId()); miaoshaOrder.setUserId(user.getId()); orderDao.insertMiaoshaOrder(miaoshaOrder);

    redisService.set(OrderKey.getMiaoshaOrderByUidGid, ""+user.getId()+"_"+goods.getId(), miaoshaOrder);

    //最后将哪个用户买了哪件商品放入redis,用于以后判断是否为重复秒杀

    5.客户端轮询,是否秒杀成功。

    接口的定义:

    /**

    * orderId:成功

        -1:秒杀失败 

         0: 排队中

    */

    @RequestMapping(value = "/result", method = RequestMethod.GET)

    @ResponseBody

    相关文章

      网友评论

          本文标题:秒杀接口优化

          本文链接:https://www.haomeiwen.com/subject/ogmplftx.html