秒杀接口优化

2018-04-30  本文已影响0人  totohui

秒杀接口优化

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

上一篇 下一篇

猜你喜欢

热点阅读