一个程序员的一个错误在45分钟内让一家上市公司倒闭,但工程师DougSeven却亲眼目睹了这一切。八年前,KnightCapitalGroup因部署失败仅用了45分钟就损失了4.6亿美元。这是一个真实的故事。虽然DougSeven没有参与到活动中,但他在后续的环节中不断提出DevOps、代码配置、持续交付等话题,希望让开发者意识到部署的重要性。到底是怎么回事?DougSeven在他的博客上分享了这个故事。故事背景本故事的主人公是美国一家从事做市、电子执行、机构销售和交易的全球金融服务公司KnightCapitalGroup。2012年,奈特是美国最大的股票交易商,在纽约证券交易所和纳斯达克市场占有率约为17%。KnightElectronicTradingGroup(ETG)平均每天交易量超过33亿笔,每日营业额超过210亿美元。各项数据显示,公司当时的经营和财务状况极佳。截至2012年7月31日,Knight的资产约为3.65亿美元。当时,纽约证券交易所计划在2012年8月1日推出新的零售流动性计划。为筹备该活动,Knight更新了他们的路由器SMARS。该路由器负责将订单发送到市场执行。SMARS的核心功能之一是从Knight交易平台的其他组件接收订单(父订单),然后发送一个或多个子订单执行。换句话说,SMARS会从交易平台接收到大量订单,并将它们分成多个较小的订单,以寻找数量匹配的买家或卖家。父订单越大,生成的子订单越多。在SMARS中,有一段旧代码叫做“PowerPeg”,已经8年没用了,这次更新的目的就是要替换掉这段代码。更新后的代码重新利用了用于激活PowerPeg功能的旧标志的功能。该代码已经过全面测试,并且还经过了一系列验证。一切看起来都很完美,没有理由出错。旧代码死灰复燃2012年7月27日至2012年7月31日期间,Knight的开发人员每天手动向公司的八台服务器部署新软件。这就是SEC文件中关于手动部署过程的内容。如果美国证券交易委员会的文件中有任何关于部署的内容,那肯定是大错特错了。然而,在部署新代码期间,Knight的一名技术人员忘记将新代码复制到所有八台SMARS计算机服务器上——他错过了其中一台。没有第二个技术人员来审查此部署。Knight的任何人都不知道,PowerPeg代码并没有从第8个服务器中删除,也没有添加新的RLP代码。Knight没有要求进行此类审查的书面程序。2012年8月1日,美国东部时间上午9:30,市场开市。Knight开始代表客户处理订单。7台正确部署SMARS的服务器开始正确处理这些订单。然而,发送到第8台服务器的命令触发了可支持的重新利用标志,并从死机中恢复了旧的PowerPeg代码。KillercodeZombieattackPowerPeg代码用于计算子订单执行时基于父订单买入或卖出的股票。PowerPeg将指示系统在父订单完成后停止发送子订单。也就是说,PowerPeg会跟踪子订单并在父订单完成时停止它们。2005年,Knight通过将此累积跟踪功能移至代码执行的早期阶段,从PowerPeg中删除了计数跟踪。当第8个服务器上的PowerPeg标志被激活时,PowerPeg功能开始路由子订单以供执行。但是由于没有根据父订单跟踪共享金额,因此它创建了一个永无止境的循环。45分钟到地狱想象一下,如果您有一个系统能够向市场发送自动、高速的订单,而无需任何跟踪程序来检查是否执行了足够的订单,会发生什么情况?没有比这更糟的了。当市场在上午9点30分开市时,很快就发现出了点问题。到上午9点31分,华尔街的许多人都清楚发生了严重的事情。市场上充斥着数量异常的库存订单。到上午9点32分,华尔街的人们都在想为什么订单没有停止,为什么没有人按下任何系统终止开关?原来是开关没有关。在交易的前45分钟,骑士占总交易量的50%以上,帮助部分股票市值上涨了10%以上。结果,其他股票因错误交易而贬值。更糟糕的是,Knight的系统在当天早些时候开始自动发送电子邮件。早在8时01分,SMAR就已经处理了符合开市交易条件的订单。邮件消息引用了SMARS,并将错误标识为“PowerPegdisabled”。上午8点01分到9点30分之间,Knight的工作人员还收到了97封邮件。可惜这些邮件并没有设计成系统警报,所以没有人第一时间看。在Knight经历的45分钟内,他们尝试了几种反制措施,试图阻止错误的交易。由于没有终止开关,他们只能尝试在实时交易环境中诊断问题。每分钟,大约有800万股股票在该系统上交易。他们无法找出导致错误命令的原因,因此他们从正确部署的服务器上卸载了新代码。换句话说,他们删除了工作代码并留下了损坏的代码。这进一步放大了问题。最初,额外的父命令仅在错误部署的服务器上激活PowerPeg代码。现在,问题蔓延到所有服务器。最后,他们终于停止了系统,但此时已经进行了45分钟的交易。开盘前45分钟,市场共收到并处理了212笔母单。结果,SMARS向市场发送了数百万个子订单,导致400万笔交易,而其中154只股票的交易量超过3.97亿股。这意味着骑士资本集团在45分钟内亏损了4.6亿美元。然而,奈特的身价仅为3.65亿美元。45分钟后,美国股市最大的交易商、纽交所和纳斯达克的主要做市商Knight破产,4个月后被GetcoLLC收购。软件发布必须是可重复和可靠的所有开发和运营团队都应该从这次事件中吸取教训。仅仅构建出色的软件并对其进行测试是不够的,您还必须确保它正确地投放市场,以便您的客户获得您交付的价值。部署SMARS的工程师对此不承担全部责任,Knight设置的流程与他们面临的风险不匹配。此外,他们的流程本身就容易出错。任何时候您的部??署过程都依赖于人们积极阅读和遵循说明,您就处于危险之中。人类会犯错误。错误可能出现在指令、解释或执行中。部署需要自动化和可重复,尽可能减少人为错误的可能性。如果Knight实施了一个自动化配置、部署和测试的自动化部署系统,这个错误是可以避免的。即使您不实施完整的持续交付过程,您仍然需要遵循一些持续交付原则:软件发布应该是一个可重复且可靠的过程。尽可能自动化。
