程序員的一次失誤,在 45 分鐘裏搞垮了一家上市公司

如果有人告訴你,45 分鐘就能搞垮一家大公司,你可能會覺得有點荒謬。但工程師 Doug Seven 卻真的親歷過這樣的事情。

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/

雷鋒網雷鋒網雷鋒網(公眾號:雷鋒網)

雷鋒網版權文章,未經授權禁止轉載。詳情見轉載須知



資料來源:雷鋒網
作者/編輯:skura

如果喜歡我們的文章,請即分享到︰