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

相关推荐
树懒_Zz2 天前
记录 io.springfox 3.0.0 整合 spring boot 2.6.x 由于 springfox bug 引发问题
windows·spring boot·bug
每天进步一大步2 天前
webSokect安卓和web适配的Bug 适用实时语音场景
android·前端·bug·web
JWASX2 天前
【BUG记录】Apifox 参数传入 + 号变成空格的 BUG
java·bug·urlencoder·urldecoder
初遇你时动了情2 天前
解决react 路由切换,页面闪屏的bug
javascript·react.js·bug
老赵的博客2 天前
QString转const char* bug
bug
andlbds3 天前
解决PCL库中pcl::VoxelGrid降采样Bug
c++·bug
乌漆嘎嘎黑3 天前
XIO: fatal IO error 22 (Invalid argument) on X server “localhost:10.0“【小白找bug】
pytorch·python·bug·matplotlib·mobaxterm
curd_boy4 天前
【BUG】记一次context canceled的报错
golang·bug
乌漆嘎嘎黑6 天前
训练的Loss和输出突然全是nan【小白找bug】
pytorch·python·bug·llama·大模型权重文件
花开花落的个人博客7 天前
Jlink调试找出程序隐藏BUG
bug