你已沉沉睡去,卻突然被鬧鐘的鈴聲驚醒。揉揉眼睛,你點亮手機,發現是凌晨三點。好吧,又出問題了。
網站已經關閉,應用程式已經損壞,房間裡唯一的光亮來自你的電腦螢幕。系統中的“小幽靈”可能藏在任何地方,你的職責就是帶領團隊把它們找出來。
之後,修復一切,越快越好。
作為負責幫助各類 DevOps 初創企業打理公關事務的角色,這樣的狀況在我眼前不斷重演。即使是經驗最豐富的工程師,也很有可能因為一次重大事故而留下伴隨終身的心理陰影。
但不可否認,每一家企業都會遭遇系統故障。而且,我們距離讓線上系統像電力等即開即用的傳統設施一樣觸手可及還有很長的路要走。因此,整個行業開始積極分享故障問題與真實故事(包括建立起透明且非指責性事後取證),這也讓每位從業者逐漸擺脫了當機事件帶來的恐懼感與孤獨感。
這裡我們不會粗暴援引冷冰冰的數字,畢竟 Amazon 每小時可能遇到的上百萬個問題,而小型企業只是引發糟糕客戶體驗。但無論規模如何,企業最終總會蒙受金錢損失、聲譽損失、工程資源浪費,並導致市場地位下降。
下面,我們就單從分享經驗與加以預防的思路,聽聽 CTO 們自己講述的六個恐怖當機事件。
Charity Majors,Honeycomb 公司 CTO
“通知推送失敗!”
“不對吧,沒問題啊。”
“有問題,客戶們已經開始抱怨,推送功能中斷了。”
“推送功能不可能中斷。我們的推送仍在佇列中,我還能收到各種推送呢。”
“已經五天了,推送效率仍然很低。大家正在不斷提交各種問題。”
……沒辦法,既然都這麼說了,我只能到處找找問題。但我們所有的推送指標看起來都比較正常,我傳送的每條測試推送也都能及時完成交付。但客戶支援團隊的說法也沒錯——過去五天以來,人們確實一直在投訴推送失敗。到底怎麼回事?
這裡說的是 Android 推送通知。Android 裝置需要保證指向伺服器的套接字始終開啟,才能正確訂閱推送通知。我們擁有數以千萬計的 Android 裝置,因此需要在 autoscaling 組裡執行推送通知服務。為了對整個組內的連線進行負載均衡,我們還使用了迴圈 DNS;要想增加容量,我們只需要增加 ASG(auto-scaling 自動伸縮組)的大小即可。最終,我們發現投訴來自上一次增加 ASG 大小,這應該是個有用的線索。另一個線索在於,所有的客戶投訴似乎都來自東歐。我們抽取其中幾位,邀請他們進行更詳細的跟蹤,並發現 DNS 記錄似乎發生了丟失。
事實證明,當我們增加 ASG 的大小時,輪詢 DNS 記錄超過了 UDP 資料包的大小。正常來說這其實沒什麼問題,協議上說發生這種情況時,應該會返回繼續使用 TCP。事情也的確如此——除了少部分割槽域。羅馬尼亞一臺主路由器出了問題,因此我們將用於該記錄的 DNS 透過 Route 53 服務指派給了另一臺小型本地 Python DNS 伺服器,由該伺服器返回由四個 Android 推送通知伺服器的隨機子集。一切恢復正常,萬幸。
Matthe Fornaciari,Gremlin 公司 CTO
當機發生在星期五下午,當時我們正準備去參加萬聖節狂歡。警告頁面出現,經過一番調查,我們意識到主機中的磁碟空間已經被耗盡,並因無法繼續寫入日誌而開始出現故障。這非常可怕,因為我們無法瞭解當前的執行狀態。
最終,我們重新整理了主機、引入日誌輪替以預防再次發生此類問題,並建立警報以隨時提醒磁碟空間使用情況。除此之外,我們還指派一位工程師為平臺編寫了新的 Gremlin。這一磁碟 Gremlin 能夠幫助我們主動進行修復,徹底消除後續可能出現的同類故障。最後,我們實現了整個測試流程的自動化,目前這項測試仍然存在,直到今天仍在我們的生產環境中隨機執行。
Liran Haimovitch,Rookout 公司 CTO
還記得伺服器每天會在同一特定時間點發生當機的都市怪談嗎?經過幾個禮拜的調查,人們從監控攝像頭中發現……原來是保潔人員會定期拔下伺服器的電源,再接上吸塵器!哈哈,其實運營故障就是這樣,看似可怕、背後卻往往有著很多黑色幽默般的深層原因。
最近,我們也遇到了類似的狀況。
每個禮拜,我們都會多次發現後端延遲指標出現持續增長。而每當進行調查時,我們都注意到其中一個表被鎖定且持續出現查詢超時。我們很好奇,這是有哪位客戶在不停地重新部署自己的應用程式嗎?這種溯源查詢相當複雜,需要獲取所有客戶伺服器資訊的列表,藉此判斷哪些伺服器有待除錯。我們開始最佳化這項查詢並獲得了巨大的改進,但延遲峰值問題始終沒能得到解決。
幾個禮拜之前,在參加每週“客戶成功簡報”時,等待時長再次出現峰值。突然之間,我意識到應用程式的後臺中存在一個我們幾乎從不使用的查詢,它的速度也的確很慢,我們從來沒有考慮過優先加以修復(畢竟很少使用)。顯然,我們的客戶成功經理一直在收集#會議資料,在每次查詢返回結果的速度不夠快時,他都會不斷重新整理並重試。就是這項極少使用的查詢鎖死了我們的資料庫,最終造成了神秘的延遲現象。透過資料審查,我們確認所有延遲峰值都與客戶成功簡報會議相符。於是,我們最佳化了該查詢。大約 20 分鐘之後,一切恢復正常。
Daniel “Spoons”poonhower,Lightstep 公司 CTO
那是舊金山陽光明媚的一天,我在一家小型網際網路企業工作。突然之間,應用程式停止了正常載入。不只是當前檢視,是整個應用程式都陷入癱瘓。我重灌了一下,但還是不行。我望了望四周,同事們顯然也遇到了問題。雖然使用者還沒有發出投訴,但我們必須趕快行動。那天我們沒有進行任何部署,基礎設施方面也沒做出調整。但應用本身在各種作業系統和瀏覽器上都一概不給面子……到底出了什麼問題?
我們在幾項關鍵 API 呼叫中發現了一些錯誤,但解決之後,應用仍然無法載入。更要命的是,為什麼只有公司內部員工遇到了無法載入的問題?事實證明,該 API 會為內部使用者返回一些額外的資料。而過去幾周之內,這些額外資料一直在緩慢增長,最終在當天下午超過了請求的最大有效載荷。
Lee Liu,LogDNA 公司 CTO
我們使用的 AddTrust 根證照分發機構(CA)於 2020 年 5 月 30 日星期六約凌晨 4 點時過期了。
當時,我們正將部分基礎設施遷移至非營利性證照分發機構 Let’sEncrypt,這也是公司 Kubernetes 遷移計劃的一部分。舊版 Syslog 客戶端需要使用 AddTrust/UserTrust/Comodo。除了由雲合作伙伴提供的全球基礎設施環境之外,我們還執行有自己的 SaaS 環境。在這套內部 SaaS 環境中,到處都在使用同一條證照鏈,包括我們的接收端點、Syslog 端點以及 Web 應用程式等。我們以為自己已經為根證照到期做好了準備……但事實證明,並沒有。
證照鏈快速入門:所有基於證照的安全機制都依賴於信任鏈。瀏覽器及作業系統附帶有根證照的信任儲存庫。
LogDNA 鏈:
AddTrust 根 CA(5 月 30 日到期) ->UserTrustCA ->Sectigo-> *.[logdna.com]()
現代瀏覽器允許:
UserTrustCA ->Sectigo-> *.[logdna.com]()
UserTrustCA 本身同時也是大部分瀏覽器中根信任儲存庫的一部分,因此即使 AddTrust 過期,由於通往 UserTrustCA 的鏈仍然有效,因此問題將被忽略。
或者,這只是我們的一廂情願。
事實證明,舊有系統只能識別到 LogDNA 鏈。如果四份證照中的任何一份過期,則該鏈將成為無效鏈。此外,舊系統不會將 UserTrust 識別為受信根證照。
我們收到的所有支援通知,都提到 v1 代理將不再將日誌傳送至我們的接收端點;但我們的 v2 代理及其他基於 REST API 的現代客戶端實現都能夠正常工作。
帶著錯誤的預判,我們對 v1 代理進行更新。更加諷刺的是,由於同樣的 AddTrust 根 CA 到期問題,我們的 CI/CD 供應商也出現了問題,並導致代理的部署流程變得更為複雜。在意識到問題出在實際證照鏈與舊有系統無法相容之後,我們快速切換至基於 Let’s Encrypt 的新證照鏈、成功修復了系統。
Tina Huang,Transposit 公司 CTO
全站當機確實非常可怕,但更可怕的是那種隨機出現、無法預測的故障。當時,我正在處理 Twitter 的移動版本。有客戶反映稱,對於某些在戶外使用這款應用的群體,每當訪問網站時看到的只有錯誤提示頁面。但問題的發生機率不高,絕大多數使用者仍然能夠看到正常的介面。這就很讓人頭大,我們肯定不能直接忽略這個隻影響少數群體的嚴重問題。
慢慢的,受影響賬戶的數量開始增加,500 伺服器內部錯誤量也開始攀升至臨界水平。可以看到,我們當前使用的新庫無法解析具有特定字元的會話 cookie。因此,每當使用者重新登入時,都會被這個問題所困擾。除非清空手機上的 cookie,否則問題將反覆出現。最終,我們修復了庫中的錯誤,讓每個人都能正常閱讀自己的推文……回想起來,這真是段可怕的經歷!
原文連結: