整理 | 郑丽媛
出品 | CSDN(ID:CSDNnews)
你能想象吗:仅因一行代码,导致一家公司损失了至少 6000 万美元?听起来可能颇为匪夷所思,但这件事真实发生在了美国电信公司 AT&T 的身上。
自 1877 年成立以来,AT&T 从未发生过重大网络事故,为此公司也大力宣传自家系统的可靠性和安全性。在这种背景下,到了上世纪 90 年代,当时 AT&T 已经占据了美国 70% 的长途通讯量、电话呼叫转发超过 11.5 亿次,是当之无愧的美国最大电信通讯公司。
然而 1990 年 1 月 15 日 AT&T 发生的这场重大事故,颠覆了它在人们心中“安全可靠”的固有印象:1990 年 1 月 15 日,AT&T 出现大面积系统故障,网络持续瘫痪了 9 个小时,期间 6 万多人的电话完全无法接通、7500 万个电话被错过、呼叫连接故障率高达 50%、500 个航班延误……AT&T 因此损失了超过 6000 万美元。
那么这个价值 6000 万美元的“罪魁祸首”,到底是哪行代码呢?
应管理层要求,代码没有经过测试
在发生这场重大事故之前,AT&T 维持了一百多年的稳定可靠,主要利用当时先进的电子交换机和信号系统处理了大部分电话,其系统通常能在几秒钟内完成呼叫路由选择。
按理说,既然如此 AT&T 的整个网络应该被设计得非常完善,即便单个交换机出现故障也不该引起系统崩溃,还能自主隔离有缺陷的交换机——一直以来,AT&T 也确实如此。但在事故发生前,AT&T 为了改善长途通话质量,将软件进行了更新,而这个更新中存在一个致命 Bug。
事故当天,这个 Bug 从纽约的一台交换机开始,导致整个网络都出现了故障,共影响了 114 台交换机。最初,这台纽约交换机的自检程序发现它已接近负载极限,要执行复位并发出信号时,这个 Bug 引起了多米诺骨牌效应,导致大范围的网络中断。
你或许会问:那软件更新前 AT&T 没有测试吗?这就是有趣的地方了:由于代码改动较小,因此按照管理层的要求,那次更新并没有经过测试。
美国近一半主要通信线路瘫痪
追根溯源,这个损失 6000 万美元的事故原因,是在网络交换机上实施的软件更新中出现了编码错误。具体来说,这个 Bug 是由一个非常简单的语法错误引起的:该 Bug 发生在 C 语言程序中,其中嵌套条件语句中的关键字 break 用法错误,由此导致了数据覆盖和系统重置。
伪代码如下:
以上代码存在的问题:
如果环形缓冲区不为空,则跳过第 7 行的“if”语句,转而执行第 10 行的 break 语句。
然而,为了使程序正常运行,本应执行第 11 行。
当 break 语句被执行,而不是处理传入消息并为可选参数设置指针时,数据(本应保留的指针)就会被覆盖。
纠错软件识别出数据被覆盖,便启动关闭开关进行重置。由于整个网络中的所有交换机都使用了这个有缺陷的软件,导致了连锁复位反应,最终使整个网络系统瘫痪,让问题变得更加复杂。
也就是说,尽管此前 AT&T 进行了严格测试,网络设计也非常灵活,但这次一行代码的疏忽还是导致了美国几乎一半的主要通信线路瘫痪。
网友:我敢打赌,没有管理层因此被解雇
在经历了 9 个小时的持续瘫痪后,AT&T 当时解决问题的方法是:让工程师把交换机重装回以前的软件版本。而实际上,事后 AT&T 超过 100 人的技术团队参与了此次事故分析,共花了两周时间进行严格的代码阅读、测试和复制,才最终弄清了 Bug 所在。
AT&T 的这次事故发生在 33 年前,可就算后来的公司拥有了更好工作流程,也难免会有漏网的 Bug,例如 2016 年 YouTube 也发生了首次全球故障。
作为这些发生重大故障的公司而言,其损失无疑是巨大的,因此每次也都会给他们带去相应的教训。但对大多数公司来说,很多故障归根结底都是人为错误和流程漏洞造成的。
对于一行代码导致损失 6000 万美元这件事,诸多网友也发表了自己的看法:
“这是人们在软件开发中最具挑战性的问题之一:事件原因和我们称之为‘触发器’之间存在巨大差异。导致问题的不是 1 行代码,而是这种环境使得 1 行代码就能够‘触发’问题。”
“问题在于一行代码 + 糟糕的管理,因为还有高层迫使工程师跳过测试。而且我敢打赌,没有管理层因此被解雇。”
“最可悲的地方是:管理层要求绕过测试,因为代码变化太小了。”
那么你对于这个导致了 6000 万美元损失的事故,又有什么看法吗?
参考链接:
https://shimo.im/docs/9030J9eOGnc0n7kw
https://www.reddit.com/r/programming/comments/17uemqw/one_line_of_code_caused_att_to_lose_60_million/
领取专属 10元无门槛券
私享最新 技术干货