【黑马点评】jmeter测试秒杀接口前后耗时,和查询店铺缓存穿透接口

这篇是测试,使用RabbitMQ消息异步处理订单,以及不异步处理订单的耗时对比
以及查询店铺时使用redis+caffeine二级缓存接口

4.测试秒杀接口耗时

需要修改VoucherOrderController中的秒杀代码,在秒杀操作前后计算接口耗时

4.1 修改VoucherOrderController

注释掉原先的seckillVoucher方法

//    @PostMapping("seckill/{id}")
//    public Result seckillVoucher(@PathVariable("id") Long voucherId) {
//        return voucherOrderService.seckillVoucher(voucherId);
//    }

改为

    @PostMapping("seckill/{id}")
    public Result seckillVoucher(@PathVariable("id") Long voucherId) {
        long startTime = System.currentTimeMillis();
        Result  result = voucherOrderService.seckillVoucher(voucherId);
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        log.info("秒杀接口耗时:{}ms",duration);
//        return voucherOrderService.seckillVoucher(voucherId);
        return result;
    }

之后,使用Apifox发起测试

在这里插入图片描述

命令行输出结构为:3ms

在这里插入图片描述

4.2 测试原本的接口耗时

修改VoucherOrderServiceImpl.java代码如下

主要注释掉如下三个方法

  • handleVoucherOrder
  • seckillVoucher
  • createVoucherOrder
    // @TODO 注释掉以下部分,以下部分为用RabbitMQ实现的异步秒杀
//    @Transactional
//    public void handleVoucherOrder(VoucherOrder voucherOrder) {
//        //1.所有信息从当前消息实体中拿
//        // 获取用户
//        Long userId = voucherOrder.getUserId();
//        //创建锁对象
//        RLock redisLock = redissonClient.getLock("lock:order:"+userId);
//        //尝试获取锁
//        boolean isLock = redisLock.tryLock();
//
//        //4.判断是否获取锁成功
//        if(!isLock){
//            //获取锁失败,直接返回失败或者重试
//            log.error("不允许重复下单!");
//            return;
//        }
//        try{
//            //获取代理对象(事务)
//            IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
//            proxy.createVoucherOrder(voucherOrder);
//        }finally {
//            if (redisLock.isHeldByCurrentThread()) {
//                redisLock.unlock();
//            }
//        }
///*        Long voucherId = voucherOrder.getVoucherId();
//        //2.扣减库存
//        boolean success = seckillVoucherService.update().setSql("stock=stock-1")
//                .eq("voucher_id", voucherId)
//                //======判断当前库存是否大于0就可以决定是否能抢池子中的券了
//                .gt("stock", 0)
//                .update();
//        //3.创建订单
//        if(success) save(voucherOrder);*/
//    }
//
//
//    @Resource
//    RabbitTemplate rabbitTemplate;
//    @Override
//    public Result seckillVoucher(Long voucherId) {
//        //1.执行lua脚本,判断当前用户的购买资格
//        Long userId = UserHolder.getUser().getId();
//        Long result = stringRedisTemplate.execute(
//                SECKILL_SCRIPT,
//                Collections.emptyList(),
//                voucherId.toString(), userId.toString());
//        if (result != 0) {
//            //2.不为0说明没有购买资格
//            return Result.fail(result==1?"库存不足":"不能重复下单");
//        }
//        //3.走到这一步说明有购买资格,将订单信息存到消息队列
//        VoucherOrder voucherOrder = new VoucherOrder();
//        long orderId = redisIdWorker.nextId("order");
//        voucherOrder.setId(orderId);
//        voucherOrder.setUserId(UserHolder.getUser().getId());
//        voucherOrder.setVoucherId(voucherId);
//        //存入消息队列等待异步消费
//        rabbitTemplate.convertAndSend("hmdianping.direct","direct.seckill",voucherOrder);
//        return Result.ok(orderId);
//    }
//
//
//
//    @Transactional
//    public void createVoucherOrder(VoucherOrder voucherOrder){
//        // 5.一人一单逻辑
//        // 5.1.用户id
//        //6.扣减库存
//        Long voucherId = voucherOrder.getVoucherId();
//        boolean success = seckillVoucherService.update()
//                .setSql("stock= stock -1") // set stock = stock -1
//                .eq("voucher_id", voucherId)
//                .gt("stock",0)// where id = ? and stock > 0
//                .update();
//        if (!success) {
//            //扣减库存
//            log.error("库存不足!");
//            return ;
//        }
//
//
//        save(voucherOrder);
//
//    }

添加以下内容

    // 原先秒杀接口,用来测试接口耗时
    @Override
    public Result seckillVoucher(Long voucherId) {
        // 1.查询优惠券
        SeckillVoucher voucher = seckillVoucherService.getById(voucherId);
        // 2.判断秒杀是否开始
        if (voucher.getBeginTime().isAfter(LocalDateTime.now())) {
            // 尚未开始
            return Result.fail("秒杀尚未开始!");
        }
        // 3.判断秒杀是否已经结束
        if (voucher.getEndTime().isBefore(LocalDateTime.now())) {
            // 尚未开始
            return Result.fail("秒杀已经结束!");
        }
        // 4.判断库存是否充足
        if (voucher.getStock() < 1) {
            // 库存不足
            return Result.fail("库存不足!");
        }
        // 5.一人一单逻辑
        // 5.1.用户id
        Long userId = UserHolder.getUser().getId();
        int count = query().eq("user_id", userId).eq("voucher_id", voucherId).count();
        // 5.2.判断是否存在
        if (count > 0) {
            // 用户已经购买过了
            return Result.fail("用户已经购买过一次!");
        }

        //6,扣减库存
        boolean success = seckillVoucherService.update()
                .setSql("stock= stock -1")
                .eq("voucher_id", voucherId).update();
        if (!success) {
            //扣减库存
            return Result.fail("库存不足!");
        }
        //7.创建订单
        VoucherOrder voucherOrder = new VoucherOrder();
        // 7.1.订单id
        long orderId = redisIdWorker.nextId("order");
        voucherOrder.setId(orderId);

        voucherOrder.setUserId(userId);
        // 7.3.代金券id
        voucherOrder.setVoucherId(voucherId);
        save(voucherOrder);

        return Result.ok(orderId);

    }

    @Override
    public void createVoucherOrder(VoucherOrder voucherOrder) {

    }

    @Override
    public void handleVoucherOrder(VoucherOrder voucherOrder) {

    }

测试结果如下:400ms

在这里插入图片描述

5. 测试缓存穿透

修改http请求如下

在这里插入图片描述

1000并发下

在这里插入图片描述

10000并发下

在这里插入图片描述

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐