發生了什麼事
2018 年 2 月 3 日至 4 日,《Fortnite Battle Royale》達到 340 萬同時在線玩家的高峰——相較於僅數月前的 6 萬人前次高峰——而那個週末成了一場接連不斷的斷線。Epic 自己於 2018 年 2 月 8 日發布的事後檢討報告,記錄了六起各自獨立的事件,包含部分與全面服務中斷的混合情況。
最深的傷口在 MCP 個人檔案服務,其背後由九個 MongoDB 分片支撐,每秒處理 31.8 萬次讀取與 13.2 萬次寫入。媒合分片開始將寫入排入佇列,使單一操作飆升至 4 萬毫秒以上,並阻塞了所有 MCP 執行緒;它從未自行恢復,因此維運人員每小時手動執行主節點容錯切換數次。第二道傷口:一次封裝變更悄悄將該服務的執行緒數上限壓到低於預定的安全值,而近期的「修正」——將其還原——卻只在生產環境尖峰時耗盡資料庫連線池,迫使他們回滾。
週日,帳號服務於 UTC 18:30 至 20:20 中斷:Memcached 不穩定使 Nginx 在 100 毫秒逾時上阻塞,直到其工作執行緒耗盡,健康檢查被淹沒,負載平衡器便移除了所有節點——全球登入因此被封鎖。當晚,XMPP 社交層在一次緊急藍綠容錯切換中失效:重新連線的湧入壓垮了好友服務的負載平衡器,而它無法調配替代資源,因為其子網路的可用 IP 已耗盡。玩家雖然連上了線,卻看到每位好友都顯示離線——一個「暗室」。
雲端上限讓情況更糟:數千個 c4.8xlarge 執行個體逼近該區域的執行個體上限,而提供 251 個可用 IP 的 /24 子網路已被用盡,拉長了負載平衡器的恢復時間。Epic 派 MongoDB 專家到現場,承諾重新架構訊息堆疊與 MCP,並在事後檢討報告結尾附上招募訊息——一支由資深線上開發者組成的小團隊,一直讓這款全球最大的 PC/主機遊戲維持運作,直到數字成長超越了他們。
代價是什麼
2018 年 2 月 3 日至 4 日期間發生六起部分與全面中斷:登入被封鎖、媒合凍結、好友顯示離線;手動容錯切換每小時執行一次。
為何發生
媒合狀態存放在單一共享分片上;當其寫入端排入佇列時,每一項 MCP 操作都被阻塞,而唯一的恢復方式是手動主節點容錯切換。
一次封裝變更將 MCP 服務執行緒數上限壓到低於安全預設值;這項修正本身卻只在生產環境尖峰時耗盡資料庫連線池,不得不回滾。
所有帳號服務流量都經過一個 Nginx 代理,其工作執行緒在 100 毫秒的 Memcached 逾時上阻塞;工作執行緒飽和導致健康檢查失敗,負載平衡器便移除了所有節點。
好友服務的容錯切換路徑需要 /24 子網路中的可用 IP——共 251 個位址——而重新連線的湧入在事件中途就將其耗盡。
XMPP 運行全網狀叢集(101 個節點,僅叢集連結每個節點就約有 1,000 個通訊端),且有硬性的節點上限,因此社交層的容量無法單純擴充。
教訓
成長超越架構的速度,比招募能修補的速度更快:在 50 倍規模下,一個未經測試的執行緒設定、一個 251 個 IP 的子網路,以及一個熱分片,各自都會變成斷線事故。
後續
事後檢討報告的修正清單讀起來像一套重新架構計畫:與現場專家一同對 MongoDB 寫入佇列進行根因分析、將媒合工作階段移至記憶體內儲存、讓非驗證流量繞過 Nginx/Memcached 這對組合、修正子網路容量,並透過將核心服務分散到多個區域與雲端來縮小影響範圍。隨著遊戲持續成長,Epic 持續發布《Fortnite》服務更新,而這份事後檢討報告也成為標準引用案例,說明病毒式成長如何將每一項潛藏的錯誤設定轉變為斷線事故。
追溯依據
參考來源
- Postmortem of Service Outage at 3.4M CCU Epic Games (Fortnite news) · epicgames.com ·
- Postmortem of Service Outage at 3.4M CCU (archived copy) Internet Archive Wayback Machine · web.archive.org ·
- Postmortem of Service Outage at 3.4M Concurrent Users (discussion) Hacker News · news.ycombinator.com