一个线程中断引发Bug的“爆肝”排查经历

背景

在之前的版本上线了一个接收大数据推送交易数据文件的接口,这个接口要做的逻辑就是解析文件,分批入库。 当然为了数据的可靠性,以及支持重推,最终的流程大概就是这样:

上面的流程就是每日增量文件的处理流程,除此之外,还有一个历史交易数据的全量文件也需要推送过来,这个文件由于只推送一次,而且无法按照日期来支持重推,所以就约定只推一次(现在看来这里的处理方法是有点粗糙了。。),下个版本我将初始化接口对应的代码干掉。

版本上线后,业务在验证时发现不对劲,开始在开发业务验证群爆出问题:交易数据对不上! 既然不对,那就直接看看数据库,很明显的发现,数据重复了,没错就是约定只推一次的数据现在推了多次,因为初始化的全量数据并不支持多次推送。

果然还是应了那句话,需要人为介入的事情,总是会有风险,关联方的推送开关不知道怎么滴被打开了,导致了上线后每天都推送了一遍,没有等到我方系统下线对应的接口。

同时这也证明了,墨菲定律。如果你还不知道什么是墨菲定律,那我这里补充下:如果一件事有发生的可能,那么不管几率多少,总是会发生的,也可以理解为怕什么,来什么。

这也告诉大家,在平时开发相关逻辑接口时,一定要考虑各种出错场景,假设关联系统都是不可信的,确保自己的系统可以应对更多的异常场景。

对策:因为处于上线后验证期间,客户端没有上线,只有业务人员在验证使用,对应数据库表因为重推了好几份全量的数据导致数据量比较大,和运维讨论后决定删表重建后,在推一遍数据。 同时对推送文件的处理接口做防重逻辑:如果重复推送则直接异常告警

问题出现

再提交了重建表的脚本和初始化防重的代码后,当天下午移交给测试做功能测试和回归验证,准备第二天发布版本。 结果意外发生了,在执行解析入库的DB操作时报了获取不到连接异常:

看到这个异常信息后:

### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; 

想当然的以为是数据库的问题,然后考虑到有同事在复现 数据库重启后应用实例无法重新连接 的问题,第一时间重启了应用实例,结果发现依然不行,同样的错误。

既然是获取不到数据库连接,那应该整个应用实例都获取不到才对,所以去看下Myabtis的操作日志,发现其他DAO操作都是正常的。 没办法只能去看下代码,到底是哪里的问题。定位后发现是在解析数据入库这个环节报错了,具体一点就是在解析数据成功后,执行插入语句时,报了这个获取不到连接的异常。

排查过程

因为这次修复我并没有改解析入库这块的代码,只是删表重建,然后在 清理数据库(支持重推)这个环节增加了如果数据已存在则直接抛出异常的代码。

@Override
public void clearHistoryData(BigDataFileLogicParam param,String fileName) throws Exception {
   
    if (!preCheckFilePass(fileName, 8)) {
   
        OpLogUtil.logOpStep("文件预校验", "异常", param.getBizSeq(), param.getDate(), param.getFileId());
        throw new Exception("data receive has exists!");
    }
}

既然已经走到了解析入库那肯定是没有啥问题了。

那么自然而然的认为,变动点就是删表重建的sql。难道是我的建表语句写错了导致Mybatis中的字段映射不对么? 还是我使用的数据库用户新建的表,应用实例数据库连接串使用的用户没有访问权限

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值