我的亲历:一行代码,百万人民币打水漂

白帽公社
• 阅读 735
导读:几年前,我刚进入职场,作为程序员走上了技术这条路,不久便亲身经历了一件特别震撼的事情。那是一行代码引发的线上故障,故障造成了百万级的资金损失。时至今日,我依然印象深刻,也正是这件事,让我在职业生涯初期就形成了敬畏代码,严谨做事的态度。时间过去的比较久,我脑海里的细节也存在失真。我将尽量还原事件的重点信息,分享我的感受和思考,希望能带给你启发。

一次寻常的发布

如往常一样,又来到了一个发布窗口,这次发生变更的迭代很简单,是支持全链路压测的一个功能上线。

我们团队负责的是一个底层核心系统,链路上会有上百个应用依赖,为了应对大促这种超高流量的场景,大促前有一轮又一轮的压测。在首轮压测时,便发现我们的系统上有个数据库表不支持压测,导致压测计划无法进行。因此团队有位同事 A 就起了紧急迭代,针对业务依赖的这个数据库表做压测改造,代码变更也就几行。

与此同时,同事 B 在这个系统上也想改下代码,就搭了压测改造的车,两块变更一起发布。

同事 A 负责走发布流程,我们的系统有几百台服务器,部署会分为好几组,通常会搞到很晚。那天晚上,我也和大家一样,回去的比较晚,而且还忘带了手机充电器。

回去没多久,我的手机就自动关机了,想着第二天到公司再充电。

故障发现和止血

到了公司,给手机充上电后,就知道出事了。有大量客诉,并且出现排队现象,同时上游系统反馈有个错误码上午开始增加的特别多,一切迹象表明:对业务产生的一系列影响和昨晚的发布有关,同事 A 果断进行了代码回滚,避免了午高峰来临时将影响扩大。

代码回滚后,上游系统之前异常的错误码逐步恢复到基线水平,客满的同事也反馈不再有新的投诉进来。至此,止血工作完成。

事件缘起和善后

接下来就是定位原因和善后工作。团队内部仔细看了下本次发布提交的代码,再结合上游系统感知到的错误码,就定位到有一行代码的变更,影响了整个逻辑。

这行代码被同事 B 改成了 「return null」,而老逻辑是有具体数据的时候会返回实体信息,没有才返回 null。这个结果信息的变化,直接影响了上游的交易,从而商户收款紊乱,引起大量客诉,也造成了资金不平。

善后工作主要就是调账,安抚商户,差额的部分平台补足以及故障定级和整体复盘。调账的前提是,能知道哪些订单有问题,故障期间每个订单错误的收款户是哪个,实际上应该是哪个。产出这样一份数据是很复杂的,涉及很多业务和很多团队,光拉本次故障受影响数据就花费了一周以上。

受影响数据拿到之后基本就能知道资损的量级,也可以基于此给受影响的用户赔偿,同时给故障定级。最终资损百万级,故障级别也相当高,高到故障不能往一线员工身上挂,只能往管理层上挂。

事后就有一大帮人参与复盘,拷问本次发布的各个环节是否符合规范。有没有代码 CR,有没有测试,有没有灰度,有没有监控,有没有核对。我发现好像该有的我们都有,但事情还是这么诡异的发生了,并且是被迫发现。

诡异之处就在于同事 B 也不知道有提交过那行「return null」的代码,能找到 CR 截图但并未覆盖到那一行代码,测试只关注了压测改造的变更并没有关注到搭车的内容,灰度发布又在晚上,感知不到业务异常,监控核对有报警,但平常比较关注的我在当天刚好手机关机。

由此看来,故障的直接原因是同事 B 的代码误提交,但事实上在提交后的各个环节里都有疏漏的地方。不久之后,同事 B 和负责测试的同事就离职了。他们不需要为公司承担资金的损失,但会因此事得到不好的绩效,这可能是他们离开的原因。

我的感受和思考

当时还是职场小菜鸟的我懵懵懂懂,亲历了这么一次大故障,让我感受到代码的强大,强大的影响力和破坏力

「敬畏代码」不再是耳边的循循教导,而是要落实到工程实践中。对待代码的盲目自信,也渐渐转变成只相信测试结果。代码是人敲出来的,人会犯错,但机器不会。编写的代码不仅要经得起理论的推敲,也要挺得住实践的检验。不能想当然,每当心存侥幸的时候,你觉得不会发生的事情它还真的就会发生。严谨做事,应当成为职业工程师的基本素养。

另外就是规范的重要性。什么是规范?规范是明文规定或约定俗成的标准。人总会有疏忽,大脑会有停转的时刻,实际执行也有遗漏的时候。遵循规范,人的不可靠带来的影响可以限制在一定范围内,大大减少出错率。规范的制定,执行,调整,能够提升效率,降低风险,避免类似这次故障的低级错误。

(完)


首发于公众号「蜗牛互联网」。

点赞
收藏
评论区
推荐文章
浅梦一笑 浅梦一笑
4年前
我惊了,python一行代码玩游戏!!!!
给IT入门加星标,提升编程技能freepythongames,一行代码就能进入使用Python开发的小游戏快乐玩耍!安装pip install freegamesPython包括随您的安装一起分发的大量标准库。标准库有一个称为Turtle的模块,这是一种向普通人介绍python编程的流行方法。今天介绍的所有游戏都是使用Python及其Turtle模块实现的。
Wesley13 Wesley13
4年前
SAP SD实施笔记
今年我作为SD顾问,参与了汽车行业某公司的SAP上线实施项目。这是我第一次作为乙方SD顾问参与这么大型的项目,在实施的过程中,我有很多感悟,但是因为项目周期赶、时间紧,没有时间记录下来。现在项目上线了,我也空出时间可以好好梳理一下心得和笔记,作为对自己过去这半年的收获之一。首先,以前我就职于一家甲方公司做SD运维,作为一名职场新人,参与
Karen110 Karen110
4年前
25条很棒的Python一行代码,建议收藏!
自从我用Python编写第一行代码以来,就被它的简单性、出色的可读性和特别流行的一行代码所吸引。在下面,我将给大家介绍并解释一些Python一行程序。可能有些你还不知道,但对你未来的Python项目很有用。▍1、交换两个变量 a  4 b  5a,b  b,a print(a,b)  5,4让我们通过交换两个变量作为一个简
静坐罗汉 静坐罗汉
1年前
今天的我!
你好啊!halouwod今天天气很好啊,写一篇日记吧,记录一下美好的开始,从很久以前大概十年吧,就开始研究如何做一个有意思的人,
Stella981 Stella981
4年前
25条很棒的Python一行代码,建议收藏!
点击上方“Python爬虫与数据挖掘”,进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤中岁颇好道,晚家南山陲。自从我用Python编写第一行代码以来,就被它的简单性、出色的可读性和特别流行的一行代码所吸引。在下面,我将给大家介绍并解释一些Python一行程序。
Stella981 Stella981
4年前
Play Framework 安装
        记得有一次OSC高手问答是关于PlayFramework的,那是我第一次听说PlayFramework这个所谓的全堆栈式的java应用框架,当时也没有非常吸引我,但是它也算在我的脑海里留下了一定的印象,由于公司的文化,不得的不去尝试新的技术,作为应届生也必须努力专研才能提高自己,前几天花了一些时间去搭建开发环境,本人以前没有写博文的习惯,
Wesley13 Wesley13
4年前
C# 谁改了我的代码
本文告诉大家一个特殊的做法,可以修改一个字符串常量<!more我们来写一个简单的程序,把一个常量字符串输出privateconststringstr"lindexi";staticvoidMain(stringargs){
Stella981 Stella981
4年前
Python asyncio 与 aiohttp 使用简单记录
asyncio的基本概念asyncio是在python3.4中被引进的异步IO库。你也可以通过python3.3的pypi来安装它。它相当的复杂,而且我不会介绍太多的细节。相反,我将会解释你需要知道些什么,以利用它来写异步的代码。简而言之,有两件事情你需要知道:协同程序和事件循环。协同程序像是方法,但是它们可以在代码中的特定点暂停和继
Stella981 Stella981
4年前
C++开源代码覆盖率工具OpenCppCoverage介绍(Windows)
关于代码覆盖率统计工具,Linux平台下,gcc内置支持gcov,通过编译时加参数选项,进行代码插桩,从而实现代码覆盖率。在Windows平台下,早在几年前,我还没找到特别好用又开源的覆盖率工具,所以以前公司是自己实现了一套,使用起来也不是很方便。最近又遇到同样的问题,不过非常幸运的是,一款开源的Windows平台的C代码覆盖率工具出现了在我的面前:
从校招新星到前端技术专家的成长之路
引言我在2018年校招进入京东,主要负责广告投放系统的前端工作。在京东,这一路走来,我经历了多种角色转换,我从学生到职场人,从校招生到校招导师,从初级前端开发到前端技术专家,也见证了京东广告业务的蓬勃发展。回顾过去的成长历程,我心中充满了感慨。首先,我要衷
codigger codigger
3个月前
告别插件堆砌!Neovim 配置“瘦身”实战:用 Mini.nvim 替换主流插件全过程
转Reddit技术博主的帖子:我的Neovim插件哲学作为一名资深的系统程序员,我日常工作会处理大型的单体代码仓库(monorepos),项目文件数超过4万,代码行数超过400万。在这样的环境下,我对开发工具的要求是:极简、高效、启动快。我的插件哲学是:尽