8 年前,因为一次失败的部署,Knight Capital Group 在仅仅 45 分钟内就造成了 4.6 亿美元的亏损。
这是一个真实的故事。
尽管 Doug Seven 并不是事件的参与者,但他在后来的会议中不断提及 DevOps、代码配置和持续交付的主题,希望让开发人员意识到部署的重要性。
究竟是怎么回事?Doug Seven 在博客中分享了这个故事。
故事背景
这个故事的主角是一家名为 Knight Capital Group 的美国全球金融服务公司,它从事做市、电子执行、机构销售和交易。
2012 年,Knight 是美国最大的股票交易商,在纽约证交所和纳斯达克的市场份额约为 17%。Knight 电子交易集团(ETG)平均每日交易量超过 33 亿笔,每日交易额超过 210 亿美元。
种种数据表明,当时公司的运营和财务状况非常优秀。
2012 年 7 月 31 日,Knight 拥有约 3.65 亿美元的资产。
当时,纽约证交所正计划于 2012 年 8 月 1 日推出一项新的零售流动性计划。
为了准备这次活动,Knight 更新了他们的路由器 SMARS。这个路由器负责将订单发送到市场上执行。SMARS 的核心功能之一是接收 Knight 交易平台其他组件的订单(父订单),然后发送一个或多个子订单执行。换言之,SMARS 将从交易平台收到大量订单,并将它们分成多个较小的订单,以便找到股票数量相匹配的买家或者卖家。父订单越大,生成的子订单越多。
在 SMARS 中,有一段老旧的代码,名为「Power Peg」,它已经 8 年没被用到过了,而此次更新的目的正是要换掉这段代码。更新的代码重新调整了用于激活 Power Peg 功能的旧标志的功能。
代码经过了彻底的测试,并且还进行了一系列的验证。所有的一切都看起来很完美,找不到出错的理由。
死灰复燃的旧代码
2012 年 7 月 27 日至 2012 年 7 月 31 日期间,Knight 的开发人员每天手动将新的软件部署到公司的 8 台服务器上。这就是 SEC 文件中关于手动部署过程的内容。如果 SEC 文件中有关于部署的内容,那么就可能出现了严重的错误。
然而,在新代码的部署过程中,Knight 的一名技术人员忘记将新代码复制到所有 8 台 SMARS 计算机服务器中——他漏掉了其中一台服务器。
没有第二个技术人员来审查这个部署。
Knight 的所有人都没有意识到,Power Peg 代码并没有从第 8 个服务器上删除,也没有添加新的 RLP 代码。Knight 没有书面流程要求这样的审查。
2012 年 8 月 1 日,在美国东部时间上午 9:30,市场开盘。Knight 开始代表客户处理订单。
具有正确 SMARS 部署的 7 台服务器开始正确处理这些订单。然而,发送到第 8 台服务器的命令触发了可支持的重新利用标志,并从死地中恢复了旧的 Power Peg 代码。
杀手代码如僵尸般的攻击
Power Peg 代码用于在执行子订单时,根据父订单计算购买或者出售的股份。Power Peg 将指示系统在完成父订单后停止传送子订单。
也就是说,Power Peg 会跟踪子订单,并在父订单完成后停止它们。
2005 年,Knight 将这种累计跟踪功能移到了代码执行的早期阶段,从而从 Power Peg 中删除了计数跟踪。
当激活第 8 台服务器上的 Power Peg 标志时,Power Peg 功能开始路由子订单以供执行。但由于没有根据父订单跟踪共享量,造成了一个永无止境的循环。
地狱 45 分钟
想象一下,如果你有一个系统,它能够向市场发送自动化的、高速的订单,且没有任何跟踪程序来检查是否执行了足够的订单,会发生什么?没有比这更糟糕的事了。
上午 9:30 开市时,人们很快就知道出了问题。到上午 9 点 31 分,华尔街的许多人都清楚发生了一些严重的事情。市场上充斥着非正常交易量的股票订单。
到上午 9 点 32 分,华尔街的人们都在想,为什么订单还没有停下来,为什么没有人按下任何系统的关闭开关?结果他们发现,并没有关闭开关。在交易的前 45 分钟里,Knight 的交易量占了总交易量的 50% 以上,这使得某些股票的市值上涨了 10% 以上。因此,其他股票因错误的交易而贬值。
更糟糕的是,Knight 的系统在当天早些时候开始自动发送电子邮件。早在上午 8:01,SMAR 已经处理了符合上市前交易条件的订单。邮件消息引用 SMARS,并将错误识别为「Power Peg disabled」。
在上午 8:01 到 9:30 之间,Knight 工作人员也收到了 97 封邮件。可惜的是,这些电子邮件不是作为系统警报设计的,因此没有人立即查看它们。
在 Knight 经历的 45 分钟内,他们尝试了几种反制措施,试图阻止错误的交易。由于没有终止开关,所以他们只能在实时交易环境中尝试诊断问题。
每分钟,系统上约有 800 万股股票被交易。他们无法确定是什么导致了错误的命令,所以他们从正确部署的服务器上卸载了新代码。
换句话说,他们删除了工作代码,留下了损坏的代码。
这更加放大了问题。最开始,仅在部署不正确的服务器上,额外的父命令激活了 Power Peg 代码。现在,问题蔓延到了所有服务器上。最后,他们终于停止了系统,但此时已经进行了 45 分钟的交易。
在开盘的前 45 分钟,市场收到并处理了 212 份父订单。因此,SMARS 向市场发送了数以百万计的子订单,产生了 400 万笔交易,而其中 154 只股票的交易量超过了 3.97 亿股。这意味着,Knight 资本集团在 45 分钟内造成了 4.6 亿美元的亏损。
然而,Knight 只有 3.65 亿美元的资产。
45 分钟后,美国股市最大的交易商、纽约证交所和纳斯达克的主要做市商 Knight 破产,4 个月后被 Getco LLC 收购。
软件发布必须可重复、可靠
所有开发和运营团队都应该从这次事件中吸取教训。仅仅构建优秀的软件并对其进行测试是不够的,你还必须确保它被正确地交付给市场,这样你的客户才能获得你所交付的价值。
部署 SMARS 的工程师并不是此事唯一的责任人,Knight 设置的流程和他们所面临的风险并不匹配。此外,他们的流程天生就容易出错。任何时候,如果你的部署过程依赖于人主动阅读和遵循说明,那么都将面临风险。人是会犯错的。错误可能出现在指令中,也可能出现在指令的解释中,或出现在指令的执行中。
部署需要自动化,并且可重复,尽可能避免潜在的人为错误。如果 Knight 实现了自动化部署系统,将配置、部署和测试全部自动化,那么这次错误本可以避免。
即使没有实施完整的连续交付过程,你仍然需要遵守的几个连续交付原则:
软件发布应该是一个可重复、可靠的过程。
尽可能地自动化。
via:https://dougseven.com/2014/04/17/knightmare-a-devops-cautionary-tale/