導讀:一家擁有 4 億美元資產(chǎn)、日均交易額超過 210 億美元的公司,因為一次失敗的部署,居然在 45 分鐘內(nèi)破產(chǎn)了。你也許聽說過這個故事,卻未必知道完整細節(jié)。 在之前的一個技術大會上,我發(fā)表了一個與 DevOps、配置即代碼和持續(xù)交付相關的演講。我用本文的故事說明了完全自動化和可重復的部署對于 DevOps 和持續(xù)交付來說是多么的重要。自從那次大會之后,有一些人希望我能夠通過博客來分享接下來這個故事。需要說明的是:這個故事是真實的,它真的發(fā)生過。 故事背景騎士資本集團(Knight Capital Group)是美國一家全球性金融服務公司,從事市場營銷、電子執(zhí)行、機構銷售和電子交易等方面的業(yè)務。2012 年的時候,騎士還是美國最大的股票交易商,在紐交所和納斯達克的市場份額分別為 17% 左右。騎士電子交易部門 (ETG)的日均交易量超過 33 億筆,日均交易額超過 210 億美元。 截止 2012 年 7 月 31 日,騎士集團還擁有約 3.65 億美元的現(xiàn)金和現(xiàn)金等價物。 紐約證券交易所計劃在 2012 年 8 月 1 日推出一個新的零售流動性計劃(該計劃旨在通過像騎士這樣的零售經(jīng)紀人為散戶投資者提供更好的定價服務)。為了準備這次活動,騎士升級了他們的自動化高速算法路由器,這個路由器將訂單發(fā)送到交易市場去執(zhí)行,也就是所謂的 SMARS。SMARS 的一個核心功能是接收來自騎士交易平臺其他組件的訂單 (“父”訂單),然后將一個或多個“子”訂單發(fā)送到交易中心。換句話說,SMARS 會從交易平臺收到大訂單,并將其分成多個較小的訂單,以便找到與股票交易量匹配的買家 / 賣家。父訂單越大,生成的子訂單就越多。 對 SMARS 的更新是為了替換被稱作“Power Peg”的老舊代碼,后者在騎士集團已經(jīng) 8 年沒有使用過了。(為什么已經(jīng)廢棄 8 年的代碼仍然被保留在代碼庫中?這是一個謎,但這不是重點)。更新后的代碼使用了一個舊標志,可用來激活 Power Peg 功能。代碼經(jīng)過了全面的測試,證明可以可靠地運行。 一切好像都沒什么問題,黑天鵝事件卻在不經(jīng)意間來臨了,并最終在 45 分鐘內(nèi)擊垮了這家公司。 究竟哪里出了問題?在 2012 年 7 月 27 日至 2012 年 7 月 31 日期間,騎士每天會手動將新版本部署到八臺服務器上。這就是美國證券交易委員會文件中所說的手動部署過程(順便說一句,如果美國證券交易委員會文件提到了部署相關東西,可能意味著出現(xiàn)了嚴重的錯誤)。 在事發(fā)后的 2013 年 10 月 16 日美國證券交易委員會第 70694 號文件中,我們才了解到當時發(fā)生了什么: “然而,在部署新代碼期間,騎士的一名技術人員沒有將新代碼復制到所有的 SMARS 計算機服務器上,而是漏掉了其中的一臺。沒有其他技術人員負責評審這個部署過程,也沒有人知道 Power Peg 代碼并沒有從第八臺服務器上刪除,第八臺服務器也沒有部署新代碼。騎士沒有正式的書面程序要求進行這樣的評審?!?/p> 2012 年 8 月 1 日美國東部時間上午 9 點 30 分,股市開盤,騎士開始代表客戶處理新零售流動性計劃訂單。部署了新代碼的七臺 SMARS 服務器開始處理這些訂單,但發(fā)送到第八臺服務器的命令觸發(fā)了使用舊代碼的標志,激活了 Power Peg 功能。 來自僵死代碼的進攻我們有必要了解一下 Power Peg 代碼是干什么用的。在執(zhí)行子訂單時,它會根據(jù)父訂單計算購買 / 出售的股票數(shù)量。一旦父訂單執(zhí)行完成,Power Peg 會指示系統(tǒng)停止路由子訂單。也就是說,Power Peg 會跟蹤子訂單,并在父訂單完成后停止發(fā)送它們。早在 2005 年,騎士就將這個累計跟蹤功能移到了代碼執(zhí)行的較早階段(因此從 Power Peg 中刪除了計數(shù)跟蹤功能)。 當?shù)诎伺_服務器上的 Power Peg 功能被激活后,它開始路由子訂單,但卻沒有根據(jù)父訂單的情況跟蹤股票數(shù)量,這有點像一個死循環(huán)。 地獄 45 分鐘想象一下,如果你有一個系統(tǒng),它會向市場自動快速發(fā)送訂單,但不跟蹤是否已經(jīng)執(zhí)行了足夠多的訂單,會發(fā)生什么?是的,后果很嚴重。 上午 9 點 30 分股市開盤,人們很快就知道出了問題。到上午 9 點 31 分,華爾街有很多人都清楚地看到一些嚴重的事情正在發(fā)生。股市上充斥著一些非正常交易量的股票訂單。上午 9 點 32 分,華爾街的人開始尋思著為什么問題沒有得到解決?為什么沒有人使出必殺技來解決這個問題?事實是,根本就沒有所謂的必殺技。在頭 45 分鐘里,騎士的訂單交易量占比超過 50%,將某些股價推高了 10%,而其他一些股價因錯誤交易而下跌。 更糟糕的是,騎士的系統(tǒng)在當天早些時候就開始自動發(fā)送電子郵件了——早上 8 點 01 分。電子郵件提到了 SMARS,其中有一個錯誤是“Power Peg 已禁用”。在上午 8 點 01 分至 9 點 30 分之間,有 97 封郵件被發(fā)送給騎士的員工。當然,這些郵件不算是系統(tǒng)告警,所以沒有人去查看它們。 在這地獄般的 45 分鐘內(nèi),騎士嘗試了幾種應對措施,試圖阻止錯誤的交易。但并沒有什么必殺技可用(也沒有關于如何應對這類情況的正式程序),所以他們只能試著在每分鐘處理 800 萬股交易的實時交易環(huán)境中診斷問題。由于他們無法確定是什么原因?qū)е铝隋e誤的發(fā)生,所以打算將服務器上新部署的代碼回滾。換句話說,他們移除了可以運行的代碼,留下了壞代碼。這樣做只會將問題放大,導致更多的父訂單在所有服務器上都激活了 Power Peg 功能。最終,在經(jīng)過了 45 分鐘的交易后,他們停止了系統(tǒng)。 在開盤后的 45 分鐘內(nèi),Power Peg 代碼收到并處理了 212 個父訂單。SMARS 向交易市場發(fā)送了數(shù)以百萬計的子訂單,總共有 400 萬筆交易,涉及 154 支股票,總量 3.97 億股。用外行的話說,騎士在 45 分鐘內(nèi)就虧損了 4.6 億美元。但騎士只有 3.65 億美元的現(xiàn)金和現(xiàn)金等價物。在 45 分鐘內(nèi),騎士從美國最大的股票交易商和紐約證券交易所及納斯達克的主要做市商變成了一家破產(chǎn)企業(yè)。他們有 48 小時的時間來籌集彌補損失所需的資金(他們也的確成功地從大約 6 個投資者那里獲得了 4 億美元的投資)。但是,騎士最終被 Getco LLC(2012 年 12 月)收購,合并后的公司叫作 KCG Holdings。 學到的教訓所有的開發(fā)和運營團隊都應該引以為戒。開發(fā)出好的軟件,經(jīng)過全面測試還遠遠不夠,還需要確保它們被正確地交付給市場,讓客戶獲得軟件交付的價值(這樣就不會讓你的公司破產(chǎn))。在這次事件中,部署 SMARS 的工程師并不是唯一的罪魁禍首——騎士的開發(fā)部署流程并沒有考慮到他們所面臨的風險。此外,他們的流程(甚至是沒有流程)天生就容易出錯。不管在任何時候,只要部署過程依賴人工閱讀和遵循指令,那就是將自己暴露在風險之中。人是會犯錯誤的。錯誤可能出在指令上、指令的解釋上或指令的執(zhí)行上。 部署應該是自動化且可重復的,并且盡可能避免潛在的人為錯誤。如果騎士的部署系統(tǒng)是自動化的——包括配置、部署和測試——那么這次事件就可以避免。 以下是適用于持續(xù)交付的兩個原則:
你還見過哪些因為研發(fā)、部署流程問題而引起重大故障的 IT 事件?可以在評論區(qū)說說。 ![]() |
|