本帖最后由 Rakbow 于 2025-10-23 00:04 编辑
===================================
2025.10.21更新一下
看了两天终于把生产上的脏数据还原回正常数据了,也知道为什么会出现这么**的bug了
这个功能本身业务逻辑很简单,但每个环节都会出小问题,然后也没人发现,这些小问题产生的脏数据会继续影响后续业务,然后滚了三个月雪球,知道我入职后的某一个风和日丽的下午,直到一位交易员选择导出数据时才发现这坨大shit
功能简要描述,就是交易员选择未确认的交易指令,推送到后台执行确认逻辑
首先问题1,交易指令是每日定时脚本生成的录入表里的,没有主键没有主键,而是用三个字段(业务日期,指令序号,指令次序号)当联合主键,且也没加联合约束,纯靠代码逻辑来约束,我草立德太变态了
问题2,后端逻辑写的乱七八糟,本来是拿所有指令以日期为key分组,然后在各自分组里用指令序号和次序号进行更新操作,然而之前的老哥写错了,没用分组结果for循环,而是继续拿传来的所有数据循环,分组分了个寂寞了本来到这一步就该让人奇怪的,这么写竟然在刚上生产环境时没出问题?
后来查看需求变更记录才破案,原来这个功能最开始强制要求交易员选日期筛出数据再操作,这样传到后台的指令的业务日期都是同一天的,就算for写错了也没问题,分组照样分了个寂寞(别问为什么前端只能选同一天的指令,而后端却要对不同日期分组处理,只能说在这种规范管理下前后端各写各的,能调通接口属实是天时地利人和)
直到两个月前某一天,交易员嫌每次都要选日期很麻烦,且可能会有不同天数的未确认指令,交易员懒得一天一天的批量确认,所以交易员让前端把选日期的前置操作优化了,然后直接进界面全选一把梭
于是就出现了选择多条不同日期加多个序号组合(指令序号+指令次序号)能拼出无数多的个key的神奇情况,导致一些属于其他交易员的指令,或者当前交易员没有授权的基金产品的交易指令都能被更新,甚至这个接口不止更新还能新增,刚才那一坨拼出来的不存在的key就被当成新数据新增了。。。
再加上前端没有锁界面的设置(就是点一个按钮,在请求得到响应结果前锁界面不给继续操作,我工作3年了第一次见过这种前端项目,甚至还是和钱有关的证券基金系统。。。。)
而且也没有分页(因为最开始交易员不想一页一页确认,这时候你可能会问那为什么还要把数据全传回前端,直接整个一键全部批量推送确认的接口不就行了吗,别问,问就是一天一天确认交易指令的仪式感,前面几天可能会一条一条看,后面就懒得看了直接进界面列表左上角全选一把梭哈)
就在这种神奇前端+神奇后端的组合下,交易员进界面,数据太多卡爆了,列表左上角全选一键梭哈,然后界面转圈圈请求半天没响应,交易员疯狂点确认,后端拼出一堆虚空key和大量重复key,确认到其他交易员的指令或者当前交易员未被授权的基金产品的交易指令,虚空key重复生成的超绝巨量脏数据被识别为未交易指令继续出现在其他交易员的交易列表中,其他交易员继续进界面全选一把梭哈,无限滚雪球滚了2个多月
[查看图片]
到家了写不下去了,等明早上班在地铁上再写后续
===========以下原文=========================================================================
一家普通的证券基金公司
刚入职两周,就遇到了逆天功能
至于为啥不跑路,是因为之前躺了一段时间,空窗期太长了(一年半),找了一个月才找到工作
前情提要可以看看这个帖子,
https://www.tsdm39.com/forum.php ... st&pid=76728545
是我刚入职几天时发的,简单介绍了下逆天的开发环境
这里简要铺垫一下
1.因为数据保密,理论上分为开发环境,测试环境,uat环境,生产环境,各个环境之间数据和接口彼此隔离。因为各个项目服务之间都相互依赖,且还有一堆外围接口和服务。公司大部分人都嫌麻烦,再加上技术规范管理不严格,久而久之各个小组负责的项目的开发环境都缺少维护,相当于废了。最后大伙都把测试环境当开发环境来用。
那么问题来了,出了bug要怎么找出问题呢,因为没法本地运行打断点一步步排查,只能在写的时候祈求一把过,在关键节点加打印日志,出了问题就去服务器调取日志看报错信息排查问题
2.对于数据管理非常混乱,表和视图相关sql没有统一管理,导致一张表里的字段信息基本看当初创建表的人良不良心有没有写注释,枚举类字段没有文档说明,只能去看源码
3.代码规范更是重量级,乱中爆乱,基本上能在各大码农社区看到的吐槽代码规范混乱的段子你都能在我们公司见到(没开玩笑,认真的)
4.需求文档这种东西基本等于没有,除非要离职了,就会象征性的写个信息含量基本等于0的交接文档
好,铺垫到此结束,正文开始
========================
入手第二周,业务员发现了生产环境里有个“小”bug,这个功能已经在生产环境上部署了3个月才被业务员发现,由于时间太久了业务员自己甚至都不记得是怎么操作才会产生bug的
前面提到过,因为没法本地打断点,且文档基本等于0,且业务员忘记了怎么操作的,所以不知道bug复现步骤
全靠自己造测试数据,一步一步走,加打断点,才“初步发现”问题所在
有一个定时任务,根据脚本每日定时生成未确认的交易指令录入表中,推送给基金经理确认
生成的交易指令,没有主键,是根据三个字段拼成的一个key来当主键用(当天日期,指令序号,指令次序号)
然后这个业务流程有点长,且这个交易指令表还关联了一堆其他表的数据
然后在后续的一堆逻辑中,这三个字段能在那一坨业务里被“更新”,这就很恐怖了,因为会产生了“主键”相同的交易指令数据
然后这个指令表关联的其他表也是根据这个“主键”来进行各自的业务流程的
然后就炸了,那一堆关联数据被更新的乱七八糟,关联关系炸裂中的炸裂
我所在小组的技术组长一开始也以为是个小bug所以分给我看,但我在看的过程中因为有些地方理解不了就去问他让他看看,问多了才发现如此恐怖的地方
,他也震惊了,我边上看他排查,他频频脱口而出“我草”
然后我实在忍不住问了一句,当初为什么要这么设计,他带着哭腔说他也不知道能写的这么逆天,但现在已经错过了重构的机会,因为在生产环境上躺了几个月了,产生了一堆实际业务数据
现在只能看看在不重构的情况下,修复bug+把数据还原回正常数据,今天看了一天只是初见端倪,具体还有哪些问题+解决方案下周再说
今天是我入职第一次加班到9点,道心破碎,一个不怎么难的小功能,在一堆负面buff叠加下就已经如此恐怖了,之后要是遇到业务逻辑稍微复杂一些的,工作难度可想而知
看着项目启动时的banner,再看着聊天记录里技术组长那一句“我草”,只能感慨钱难赚shit难吃
[查看图片]
[查看图片]