谷歌服務中斷事故能否避免?

圖靈君導讀

當地時間12月14日凌晨3點47分,谷歌遭遇大面積技術故障,多項服務受影響,直到約45分鐘後才恢復。谷歌在聲明中稱本次事故的原因是“內部存儲配額問題”。

可以想象,谷歌有多少工程師度過了一個不眠之夜?在分佈式系統上線後,開發人員和運維人員到底能不能高枕無憂?當出現問題時,系統能否依然穩定運行?

邁克爾·尼加德是擁有20餘年經驗的運維專家。他在《發佈!設計與部署穩定的分佈式系統(第2版)》一書中分享了一些案例。今天,圖靈君就給大家分享其中一個案例:屋漏偏逢連夜雨。請移至文末了解本書詳情。

寶寶的第一個感恩節

我的客戶在夏天新推出了一個電商系統。推出產品之後那幾周和幾個月的經歷,一次又一次地證明:新推出一個網站就像養一個寶寶,某些事情必然會發生,例如半夜被喚醒,然後被告知一些“可怕”的發現,就好比聽到“天吶!你給孩子餵了什麼……橙色橡皮泥嗎?”然而,在處理完這個新系統遇到的所有問題之後,我們仍可以持謹慎樂觀的態度去迎接這個假日季。

我們的樂觀態度源於幾個因素。第一,生產服務器的數量幾乎翻了一番。第二,我們有可靠的數據顯示該網站在目前的負載下能穩定運行。第三,我們有信心應對網站出現的任何錯誤。

爲了過感恩節,有些同事在週末加班,從而在感恩節休假。我有4天假期,於是帶着妻兒去父母那團聚,喫感恩節大餐,他們的住所跟我們隔了3個州。我們還在感恩節的那個週末,安排了24小時的工作現場值班。正如我所說的,我們抱着謹慎樂觀的態度行事。當然,作爲一名前童子軍成員(口號是“時刻準備着”),去父母家之前,我將筆記本電腦塞進了家用小貨車,以防萬一。

把脈


當星期三晚上抵達父母家時,我立即在父母的家庭辦公室裏安置好了筆記本電腦,我可以在任何有寬帶和手機的地方工作。憑藉父母家的3兆有線寬帶,我使用PuTTY登錄跳板機,並啓動我的採樣腳本。

在新推出這個網站之前的準備階段,我參與了負載測試。測試完成後,大多數負載測試提供了測試結果。由於數據來自負載生成器而不是被測系統內部,因此這是一個“黑盒”測試。爲了從負載測試中獲得更多信息,我開始使用應用程序服務器的圖形用戶界面,檢查一些重要的指標,如延遲、空閒堆內存數量、活動的請求處理線程數量和活動的會話數量。

如果事先不知道要找什麼,使用圖形用戶界面就是探索系統的好方法。如果明確知道想要什麼,使用圖形用戶界面就會變得乏味。但如果需要一次查看三四十臺服務器,那麼使用圖形用戶界面就完全不切實際了。

爲了能從負載測試中獲得更多信息,我寫了一個Perl模塊的集合,實現圖形用戶界面屏幕抓取,並能解析HTML裏面的值。

這些Perl模塊可以讓我獲取和設置屬性值,並調用應用程序服務器的內置組件和自定義組件的各個方法。由於整個圖形用戶界面均基於HTML,因此應用程序服務器不能區別Perl模塊和Web瀏覽器。通過使用這些Perl模塊,我可以創建一組腳本,來採樣所有應用程序服務器的重要統計數據,打印出詳細信息和彙總結果,休眠一段時間,然後循環往復。

這些都是簡單的指標,但自從新網站推出以來,我們所有人都通過查看這些統計數據瞭解網站的正常“節奏”和“脈搏”,比如我們一眼就知道,7月的一個星期二中午系統是正常的。

感恩節


感恩節早上一醒來,我來不及喝完咖啡就跑進父母的辦公室查看整晚運行的數據窗口,對所看到的數據檢查再三,清晨的會話數量已經達到了正常一週中最繁忙的高峯水平。訂單數量如此之高,我不得不打電話給DBA,瞭解是否有重複提交的訂單。答覆自然是沒有。

截至中午,顧客在半天內下的訂單量,已經與過去平常一週的訂單量相同。從頁面延遲、系統的響應時間和整體網站性能這些總體指標來看,系統雖然承受着壓力,但仍處於運維標稱範圍之內。

更好的是,即使會話和訂單的數量在不斷增加,但隨着時間的推移,這些數據也在趨於穩定,這讓我在整個感恩節火雞晚餐中興高采烈。

到了晚上,這一天內的訂單量已經達到了在此之前11月的總訂單量。到午夜時分,日訂單量已經與整個10月份的訂單量持平。即使是這樣,網站還在正常運行,它通過了第一次嚴酷的負載測試。

黑色星期五


第二天是黑色星期五。用完早餐後,我走到家庭辦公室,看了一下數據。訂單數的增長趨勢甚至比前一天還要高,會話數量也增加了,但一切正常,頁面延遲仍然低至大約250毫秒。我決定帶着老媽出門買些做雞肉咖喱的食材。

當然,如果後來沒有出現可怕的錯誤,我是不會絮絮叨叨地講這個故事的。在我離開辦公桌之前,什麼狀況還都沒發生。果然,當在外邊走了一半路程時,我接到了電話。

“早上好,邁克爾。我是丹尼爾。”

“一定有麻煩了是不是,丹尼爾?”我問道。

“所有的DRP在SiteScope上都變紅了。我們一直在進行DRP的滾動重啓,但它們重啓後會立即失效。戴維已經召集了電話會議,並請你加入。”

雖然是寥寥數語,但我已從丹尼爾那裏得知,網站停機了,問題很嚴重。SiteScope模擬的其實就是真實的顧客,如下圖所示。


SiteScope變紅,表明顧客無法購物,我們正在損失收入。在一個使用ATG軟件的電商網站中,頁面請求由專用的實例處理。Web服務器通過DRP協議調用應用程序服務器,因此通常將應用程序服務器上處理請求的實例稱爲DRP。一個DRP變紅,表示應用程序服務器上處理請求的一個實例已經停止響應頁面請求。所有DRP都變紅,則意味着該網站已經停機,並且正以大約每小時100萬美元的速度流失訂單。

我立即撥進了電話會議,裏面一片嘈雜聲。顯然,會議室裏的免提電話也撥入了這個電話會議。試圖在有回聲的會議室裏分辨15個聲音,這種感覺簡直無以言表。然後,我聽到有人提醒說“網站存在問題”。是的,我們知道了。謝謝,勞駕請掛機。

生命體徵


丹尼爾給我打電話時,事故大約已經過去20分鐘了。運維中心已將問題上報給現場團隊,團隊運營經理戴維請我參與解決。與顧客可能遭受的巨大損失相比,中斷休假根本不算什麼。

事故發生20分鐘後,我們知道了以下一些情況。

- 會話數量非常高,比前一天還要高。

- 網絡帶寬使用率很高,但沒有達到極限。

- 應用程序服務器的頁面延遲很高(響應時間很長)。

- Web、應用程序和數據庫CPU使用率非常低。

- 搜索服務器這個以往常見的罪魁禍首這次倒是響應良好,其統計數據看起來沒問題。

- 幾乎所有處理請求的線程處於忙碌狀態,其中許多已處理超過5秒。

爲了獲得更多信息,我開始獲取那些有異常行爲的應用程序服務器的線程轉儲。其間,我請在會議室現場工作的那位明星級工程師阿肖克,幫忙檢查後端訂單管理系統。他在後端看到了與前端類似的模式:CPU使用率很低,大多數線程長時間處於忙碌狀態。

從我接到電話到現在已經有近一小時了,或者說,網站已經停機80分鐘了。這不僅意味着訂單流失,還意味着這次極爲嚴重的事故讓我們幾乎就要違背SLA。我討厭違背SLA,因此感到很不安。所有同事和我一樣,都很不安。

進行診斷


前端應用程序服務器上的線程轉儲顯示,所有的DRP都表現出相似的模式。有幾個線程忙着調用後端,而其他大部分線程則在等着調用後端的可用連接,等待中的線程全部被阻塞在一個沒有設置超時的資源池上。

如果後端停止響應,那麼進行調用的線程將永遠不會返回,而那些被阻塞的線程將永遠無法獲得調用後端的機會。簡而言之,所有3000個處理請求的線程,都被束縛在那裏動彈不得,這完美地解釋了所觀察到的低CPU使用率現象:100個DRP全部處於空閒狀態,一直在等待永遠不會獲得的響應。

再看一下訂單管理系統。該系統上的線程轉儲顯示,在其450個線程中,一些正忙着調用外部集成點。剩下的你也許已經猜到了:其他所有線程都在等待調用那個外部集成點。

求助專家


當訂單管理系統的技術支持工程師撥入電話會議時,我感覺像是等了半個世紀(但可能只等了半小時)。他解釋說,通常處理送貨調度的4臺服務器中,有2臺在感恩節這個週末因維護而停機,而另一臺由於未知原因失靈了。直到今天,我還是不知道爲什麼他們會在全年52個週末中,偏偏選擇這個週末進行維護!

這種情況使得流量在幾個系統之間產生了巨大的失衡,如下圖所示。


當那位接到技術支持請求的工程師檢查那臺“孤獨”的送貨調度服務器時,發現其CPU利用率已經達到100%。儘管已經多次收到CPU利用率過高的警告,但這位工程師還是沒有做出反應。該團隊經常因爲CPU利用率的瞬間峯值收到警告提示,但結果常常是誤報。之前所有的誤報,讓他們學會忽略所有CPU高利用率警告。

在電話會議上,業務負責人語氣低沉地告訴我們,市場營銷部門在感恩節前準備了新的廣告插頁,登在感恩節第二天(星期五)的報紙上。廣告上提到,所有在感恩節後第一個星期一之前在線下的訂單,均享受免費送貨上門服務。在這個持續了4小時的電話會議上,所有參會者第一次陷入了沉默。

回顧一下,前端系統是一個電商系統,擁有分佈在100臺服務器上的3000個線程,以及發生了根本性變化的流量模式(因爲廣告促銷)。電商系統發出的請求流量,淹沒了其下游的訂單管理系統。訂單管理系統擁有450個線程,它們既可能被用來處理來自前端系統的請求,也可能被用來處理訂單。而訂單管理系統發出的請求又淹沒了其下游的送貨調度系統,後者一次只能處理25個請求。

這種狀況會隨着促銷宣傳而一直持續到星期一。這簡直就是噩夢,網站已停機,而且這種情況沒有手冊可以參考。我們正處於事故的“漩渦”中,不得不硬着頭皮解決問題。

如何應對


接下來就做頭腦風暴。大家提出了許多方案,也否決了許多方案,否決的原因大多是在目前的情況下,應用程序代碼的行爲是未知的。此時唯一可行的方案逐漸變得清晰起來:停止發出如此多的請求來對訂單進行送貨調度預約。由於週末的市場營銷活動主要圍繞免費送貨上門,因此用戶下訂單的請求是不會放慢速度的。此時必須找到一種方法來抑制對送貨調度系統的調用數量,而訂單管理系統無法做到這一點。

當查看電商系統的代碼後,我們看到了一絲希望。電商系統的代碼使用了標準資源池的一個子類,管理訪問訂單管理系統的連接。實際上,它還有一個單獨的連接池,專用於處理有關送貨調度的請求。電商系統擁有一個專用於處理送貨調度連接的組件,所以我們就可以將該組件用作限流器。

要是電商系統的開發人員爲連接池添加了一個enabled屬性,那麼將其設置爲false就會使事情變得很簡單。也許他們下一步就可以這樣做。不管怎樣,把資源池中最大的連接數設置爲0也能有效地將資源池關閉。

尾聲

我編寫了一個新的腳本,可以完成重置該連接池最大值所需的所有操作。它能設置max屬性,停止服務,然後重啓服務。

通過執行一個命令,運維中心或客戶現場“指揮所”(會議室)的工程師,就可以將最大連接數重置爲任何所需的數值。我後來才知道,這個腳本在整個週末都被不斷地使用着。

電話會議結束了。我掛斷電話,去哄孩子上牀睡覺。這着實花了我一點時間,因爲他們不停地說着各種趣聞:逛公園,在草坪上的噴灑器下邊玩兒,去後院看剛出生的兔寶寶。我很喜歡聽他們聊這些。

本文節選自以下圖書

邁克爾·尼加德  著

吾真本  譯


案例研究 + 行業思想家的真知灼見

助你掌握生產環境的生存法則

原版美亞評分接近滿分
 

作者介紹


邁克爾·尼加德,程序員兼架構師,擁有20餘年的從業經驗,先後爲美國政府以及銀行、金融、農業、零售等多個行業交付過運營系統,對如何在不利的環境下構建高性能、高可靠性的軟件有獨到的見解。

譯者介紹


吾真本,本名伍斌,ThoughtWorks首席諮詢師,著有測試驅動開發入門讀物《馴服爛代碼》。工作20餘年,做過程序員、測試工程師、項目經理、敏捷教練。最近7年成功輔導10餘家大型金融和科技公司的敏捷和DevOps轉型團隊。曾主辦多場編程道場,人稱“道長”。

| 留言

你有過一輩子也忘不了的開發事故經歷嗎?歡迎跟小夥伴們分享!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章