秒杀优化: 记录一次bug排查

现象

做一人一单的时候,为了提升性能,需要将原来的业务改造成Lua脚本加Stream流的方式实现异步秒杀。

代码改造完成,使用Jmeter进行并发测试,发现redis中的数据和预期相同,库存减1,该用户也成功添加了进去,但是打开数据库的订单表,发现这条数据没有添加进去。

排查

开始以为是consumer没有收到消息,检查了一遍队列名称,consumerGroup,consumer名称都是没问题的。

然后在子线程中打了断点,然后再次启动,发现报出了一个空指针异常,定位到了是创建对象createVoucherOrder2当中Long userId = UserHolder.getUser().getId()中user居然是空,token也没失效。

emmm,最后发现是createVoucherOrder2是在子线程中调用的,已经切换线程了,自然不能再从ThreadLocal里获取对象了。

队列中存在的订单对象中包含了userId,所以正确的做法应该是从订单对象里面取。

真的是一个很容易忽略的错误。

贴相关代码

java 复制代码
        private void createVoucherOrder2(VoucherOrder voucherOrder) {
            //添加逻辑:该用户是否已经已经下过单了
            //防止黄牛恶意刷单 但是会存在和超卖相同的问题 同一个用户但是超卖了三张票
            Long userId = voucherOrder.getUserId();
            RLock lock = redissonClient.getLock("lock:order:" + userId);
            boolean tryLock = lock.tryLock();

            if (!tryLock) {
                log.error("不允许重复下单");
                return;
            }
            try {
                Long voucherId = voucherOrder.getVoucherId();
                //3.查询订单
                Integer count = query()
                        .eq("user_id", userId)
                        .eq("voucher_id", voucherId)
                        .count();
                //4.校验一人一单
                if (count > 0) {
                    log.error("无法重复下单");
                    return;
                }
                //5.库存扣减 超减问题并发量3000的情况下 超卖10张
                boolean success = seckillVoucherService.update()
                        .setSql("stock= stock -1")
                        .eq("voucher_id", voucherId)
                        .gt("stock", 0).update();

                if (!success) {
                    log.error("库存不足,下单失败");
                    return;
                }
                //6.添加订单
                voucherOrderService.save(voucherOrder);
            }catch (Exception e){
                log.error("下单失败{}",e.getMessage());
            }finally {
                lock.unlock();
            }
        }

emmm

再次启动,Mysql订单表成功添加一条数据。

Jmeter汇总报告

相关推荐
腾飞的信仰2 天前
如何快速解决程序中的BUG
bug
Everglowwwwww2 天前
【bug】通过lora方式微调sdxl inpainting踩坑
学习·计算机视觉·ai作画·stable diffusion·bug
数据最前线2 天前
创建索引遇到这个Bug,19c中还没有修复
oracle·bug
CV金科2 天前
蓝桥杯-STM32G431RBT6(UART解析字符串sscanf和解决串口BUG)
c语言·stm32·单片机·嵌入式硬件·mcu·算法·bug
DisonTangor2 天前
网传阿里云盘出现bug,可看到其他用户云盘图片
阿里云·bug
后端小张2 天前
System.out源码解读——err 和 out 一起用导致的顺序异常Bug
java·开发语言·jdk·bug
我又来搬代码了2 天前
【Android】【Bug】Activity全屏(保留底部按钮)被打断变成非全屏了
android·bug
__water2 天前
『功能项目』调整Boss技能bug【51】
c#·bug·unity引擎
johnny2333 天前
《Effective Debugging:软件和系统调试的66个有效方法》读书笔记-Part2
bug
曲大家4 天前
Java和西门子S7-1200通讯调试记录
bug