深度解读Cloudflare故障,怎么出问题的老是你?【让编程再次伟大#49】

📌 深度解读Cloudflare故障,怎么出问题的老是你?【让编程再次伟大#49】

想像網路是一個巨大的購物中心,Cloudflare就是守在門口檢查有沒有壞人(機器人)的保安。保安系統(Bot Management,簡稱BM)每隔幾分鐘就要更新一份「壞人名單」。某天,工程師在更新資料庫權限時,沒有寫清楚資料來源,導致保安系統拿到了一份「重複又太長」的錯誤名單。這個名單一拿到,保安系統立刻當機,因為它的程式碼沒有準備好處理這麼長的資料。這就像保安拿到一本錯誤的通緝名單後,不只沒抓到壞人,還把整個商場的大門鎖死,造成所有來訪的客人(網路請求)都被擋在門外,無法進入,讓全球主要的網站癱瘓了五個多小時。這證明了,即使是最厲害、最複雜的網路系統,也會因為一個看似微小的程式碼疏忽而導致全球性的大崩潰。

-----

總結 Overall Summary

2025年11月18日,全球最大的內容分發網路(CDN)服務商Cloudflare遭遇了長達五個半小時的歷史性故障,導致包括GPT和推特在內的大量頂級網路服務全面癱瘓。這次事件是繼Google Cloud和AWS故障後,半年內發生的第三起全球大型癱瘓,強烈提醒使用者,網際網路這個強大科技產物比想像中還要脆弱。故障的根源是一連串由工程師「圖方便」而引發的程式設計與架構漏洞。

事故的技術鏈條始於工程師在當日上午11:05進行的資料庫權限更新。這次更新旨在允許使用者直接讀取用於儲存機器人偵測特徵的資料庫metadata。然而,程式設計師在執行第一步時,使用了一段未明確指定資料庫名稱的SQL查詢語句。由於Cloudflare採用了具有「隱式範圍控制」的ClickHouse資料庫(而非PostgreSQL),權限變更後,該SQL語句同時抓取了兩個資料庫的系統欄位數據,返回了一份包含大量重複欄位的錯誤「特徵列表」。

負責偵測爬蟲和機器人的Bot Management (BM) 模組,在11:28定時抓取了這份錯誤數據。BM模組為了追求效率,使用了預分配記憶體,且將其上限固定為200個特徵。當超量的錯誤數據湧入時,Rust應用程式碼中的`unwrap()`函數被觸發,導致BM模組程序立即崩潰,將所有HTTP請求以錯誤代碼打回。在事發前兩小時,由於資料庫補丁的漸進式發佈,錯誤請求呈現不穩定的「過山車」曲線,一度讓工程師誤以為是外部DDoS攻擊。直到13:30,錯誤曲線穩定後,工程師才意識到問題出於內部系統,最終通過手動部署乾淨數據並關閉BM模組的定時更新功能才解決問題,整體服務於17:06恢復。

這次事故突顯了當代網際網路過度集中化的弊端,網路基建集中在少數幾家巨頭(Cloudflare, AWS, GCP)手中。同時,底層程式碼中的低級錯誤(如未過濾的SQL、固定數組大小)和架構設計上犧牲容錯性來追求速度的決策,使得整個全球網路形成了一個極為脆弱的整體。

-----

觀點 Viewpoints

1. 網際網路的基礎設施比想像中更脆弱且高度集中化:
Cloudflare、AWS和GCP等少數企業掌握了網路的關鍵基建服務。當Cloudflare這道流量「第一道關卡」失效時,能瞬間讓全球大量服務癱瘓,顯示網路缺乏去中心化的容錯性。

2. 資料庫選擇與程式設計疏忽的致命組合:
工程師使用未明確指定資料庫的SQL語句是導火線。此缺陷在Cloudflare使用的ClickHouse資料庫中被放大,因為ClickHouse採用「隱式範圍控制」,導致單一查詢返回了重複且錯誤的metadata。

3. 應用層程式碼為求效率而犧牲了穩健性:
Bot Management (BM) 模組為了加快速度,使用了固定長度的預分配記憶體(僅200個特徵),並在處理潛在溢出時採用了Rust語言中簡單粗暴的`unwrap()`函數,這直接導致接收到超量數據時整個程序崩潰。

4. 事故初期的錯誤診斷延誤了救援時間:
由於錯誤數據是漸進式發佈的,導致系統錯誤率在最初兩小時呈現不規則的起伏,使工程師誤判為是大規模DDoS攻擊,延誤了故障定位到內部系統的時間。

5. 儘管程式碼有瑕疵,新版引擎的崩潰機制卻意外立功:
新版BM引擎的`unwrap()`導致HTTP請求直接失敗並大鬧天宮,反而讓工程師迅速意識到系統出現問題。如果沒有這個崩潰機制,舊版引擎將只是靜默地放行所有外部請求,導致服務實質上停擺,但工程師可能更晚才能發現系統已失能。

6. 網路的脆弱性源於工程師為「圖方便」而走的捷徑:
無論是SQL代碼中少寫的條件、還是應用代碼中定死的數組長度,這些低級錯誤都是程式設計師為追求快速開發或高效能而做的決策,累積起來造成了系統性的高風險。

-----

摘要 Abstract

⚠️ Cloudflare故障持續5.5小時,成為該公司歷史上最長的全球性癱瘓事件。
📌 故障源頭是工程師更新資料庫權限時,使用了未明確指定範圍的有缺陷SQL查詢。
✅ Cloudflare使用的ClickHouse資料庫具備「隱式範圍控制」,導致錯誤SQL返回重複的特徵數據。
⚠️ Bot Management (BM) 模組收到超量特徵列表,應用程式碼中的`unwrap()`觸發程序崩潰。
📌 BM模組的Rust程式碼為了優化速度,對特徵列表預分配了固定長度(200個),未能處理超量數據。
✅ 故障初期因錯誤率不穩,工程師誤將內部系統問題誤判為大規模DDoS攻擊。
⚠️ 網路基建過度集中化在少數服務商,加上底層代碼的低級失誤,導致整體網路系統極度脆弱。
📌 網際網路起源於高容錯軍事系統,但如今為了發展和便利,容錯性反而越來越低。

-----

FAQ 測驗

第一題

Cloudflare故障中,工程師使用SQL代碼出現疏忽。這個疏忽為何會產生重複的特徵列表?

A. SQL語句中使用了SELECT DISTINCT,但ClickHouse未能正確執行去重。
B. 工程師誤將程式連線到一個備份資料庫,導致抓取了舊資料。
C. 由於Cloudflare使用的是ClickHouse,其隱式權限控制結合未指定範圍的SQL查詢,導致系統同時讀取了default和r0兩個資料庫的系統欄位。
D. 資料庫伺服器在更新權限時,發生了記憶體溢出錯誤。

正確答案:C
解釋:Cloudflare使用了ClickHouse而非PostgreSQL,ClickHouse的隱式範圍控制使得在權限更新後,未明確指定資料庫的SQL查詢能夠同時看到並返回兩個資料庫(default和r0)的metadata,產生了錯誤的重複特徵列表。

第二題

Bot Management (BM) 模組在接收到錯誤數據後,導致程式全面崩潰的直接應用層原因是什麼?

A. 模組使用的是老舊的C++語言,無法處理JSON格式的數據。
B. 程式設計師為了加速,在Rust代碼中將處理特徵列表的記憶體固定為200個長度,當數據超量時,程式中的`unwrap()`函數被觸發,導致程序立刻停止(panic)。
C. BM模組中的機器學習模型 classifier 接收到錯誤數據後,進入了無窮迴圈。
D. 網路防火牆偵測到超量數據,自動切斷了與BM模組的連接。

正確答案:B
解釋:BM模組使用了預分配記憶體(長度固定為200),當接收到超量的錯誤特徵列表時,Rust語言中的`unwrap()`函數會強行停止(panic)整個程序,導致所有HTTP請求被錯誤打回。

第三題

本次Cloudflare故障及影片對近年來大型網路癱瘓事件的分析,所揭示的網際網路體系結構的最大問題是什麼?

A. 網路頻寬不足,無法應對日益增長的數據流量。
B. 由於低級錯誤(如SQL缺陷和程式碼捷徑)的累積,加上網路基礎設施過度集中於少數幾家服務商,導致系統整體極易因單點故障而癱瘓。
C. 恐怖分子現在傾向於對弗吉尼亞州北部的伺服器投擲EMP武器。
D. 網路服務商對DDoS攻擊的防禦措施不足。

正確答案:B
解釋:影片強調網際網路服務過度集中化,將關鍵基建集中在Cloudflare、AWS等少數巨頭上。這種集中化,結合底層程式設計師為追求效率而犧牲容錯性的做法,使得整個全球網路變得極為脆弱。

✡ Oli小濃縮 Summary bot 為您濃縮重點 ✡

https://youtu.be/T14klX5K6mQ

*

張貼留言 (0)
較新的 較舊

廣告1

廣告2