秒杀优化: 记录一次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汇总报告

相关推荐
姚青&17 小时前
Bug基本概念
bug
AI多Agent协作实战派19 小时前
AI多Agent协作系统实战(三十九):AI修对了Bug,却越了权——自动化团队的第一条铁律
人工智能·自动化·bug
深念Y3 天前
AMD 芯片组驱动触发高频 SSD 写入的问题及解决方案
windows·bug·ssd·日志·芯片·驱动·amd
加油码3 天前
探秘 volatile关键字:编译器的过度优化
linux·bug·信号处理
鹿屿二向箔3 天前
keil5.39版本使用AC6编译器不能位域操作的BUG使用STM32U385系列MCU
stm32·单片机·bug
angryshan3 天前
goLang配置断点流程
go·bug
吨吨ai5 天前
# ChatGPT Plus / Pro + Codex Debug 实战:如何让 AI 从日志、Trace、异常堆栈自动定位线上 Bug
人工智能·chatgpt·bug
灰暗世界%6 天前
飞牛bug修复
bug
凌云拓界8 天前
NodeVerdict | 性能门禁:把追踪数据变成 CI 规则
ci/cd·信息可视化·开源·node.js·bug·数据可视化·安全架构
qingmiaozhuan9 天前
软件测试Bug复现高清录屏标准流程:新手入门与规范指南(2026实战版)
bug·电脑录屏·电脑录屏软件·测试录屏规范·音画同步录制