在Z行软件中心工作的7年里,我所在部门负责核心系统的开发维护。因为直面生产,碰到过形形色色的生产BUG,有些BUG至今想来,仍觉着有些匪夷所思。
新手学费
2011年是我参与核心系统开发维护的头一年。记得开发的第一个需求是接收SWIFT汇入报文然后进行账务处理,事前我反复进行了测试,可是一投产就出了问题,功能不能调起,搞得我怀疑人生。事后分析看,是系统中存在并行运行的SWIFT报文汇出功能;该功能与我所开发的功能在数据库资源上存在竞争,产生死锁导致汇入功能Abend,继而导致MQ消费触发器失效;汇入报文堆积在消息队列里得不到处理。那时我毕竟还是缺少经验啊。
同批次投产发生的另一个生产BUG也是因为缺少经验缴的学费。有位同事在生产上提交了统计查询类SQL;该SQL长时间运行,锁住一些表,导致需要读写这些表的生产交易一直等待;而这些交易又锁住了其他表,如此反复,整个数据库发生了锁蔓延。直观的表现就是系统响应很慢,网点无法提交交易上来。因BUG原因比较隐蔽,各路大神花了大概半天时间才准确定位。
第2个事件造成的影响很大,部门不得不专门开了一次大会强调生产重要性,我的BUG也不幸被拿到会上陪绑宣示,当时我真感觉灰头土脸啊。还记着部门领导WJW在会上算了一笔账,大意是核心系统停机半天,就会给行里带来4亿的损失,大家都从中掂量出了沉甸甸的份量。
学无止境
后来我很快成熟了起来,开发于我轻车熟路。不过,还是有翻车的时候。像费用处理时涉及外币的场景,功能投产了有近乎两年的时间,总行业务部门突然发现外币头寸不平,要求解决。问题的本质是收费时如果涉及外币,就涉及外币的结售汇,而外币结售汇的头寸信息要同步到统一的系统,由总行业务部门在外汇市场统一平仓,这样才不会发生汇率风险。可能是费用处理涉及的外币的量实在不大,所以过了这么长时间才发现。反思这件事,归根结底,银行业务还是非常复杂的,核心的账务处理只是业务的开始,还涉及到许许多多的下游系统一起配合完成全部处理。要常怀敬畏之心,不停止业务和技术上的学习。
同期杰哥处理的生产BUG也很可以提一下。杰哥是我彼时的同事,他负责的功能一段时间内时不时出现账务处理上的异常,代码和数据上看不出任何问题。杰哥不得已去生产上蹲守,终于在一周后发现了问题所在:原来是生产上一些参数与交易数据巧合碰撞,导致交易记账到了000000机构,这是一个无效的机构,所以出现错账。至于之前为什么没有这种情况,杰哥还跟业务同事沟通过,我不太记得了。不过最后的调账肯定是我处理的,我跟财务会计部的同事掰扯过,记得很清楚。
其他印象深刻的BUG,生产上取时间的函数返回空,导致日终处理中断,幸好是在夜间,没出现特别大的影响;关键是取时间的函数也会出现问题啊,这谁能想到。2016年左右的时候,核心系统又一次拒绝服务了,大家东查西查,重启大法都祭起了,还是搞不定;最后终于是穷举法起了作用,原来是CICS的日志写满了。
小心再小心
“生产上什么事情都可能发生。”这是我参与核心系统开发维护多年后不得不认同的一句话。不管多周密的部署安排,多充足的测试预演,多强的自信,在投产之夜,仍难免提心吊胆,因为多的是各种意外的情况,只能小心再小心、细致再细致。那时大家也调侃这工作,是“操着卖白粉的心,挣着卖白菜的钱”。
而今多年过去了,我早已离开Z行,可是此刻,我又想起那些事、那些人,想起那些鲜活的面孔。