如何快速處理線上故障

發表於2017-05-04

概述

線上故障通常是指大規模的影響線上服務可用性的問題或者事件,通俗點講就是:掉‘坑’裡了,這個‘坑’就是線上故障!線上故障的處理過程可以形象地表達為:‘踩坑’、‘跳坑’、‘填坑’、‘避坑’。

線上故障的處理不僅是一項技術活,更是對技術人員/技術團隊反應能力、決策能力、判定能力、組織能力的考驗。面對突發的生產故障,需要快速定位問題,找到解決方案,快速實施解決方案並不是一件容易的事情。本文主要包括如下內容:線上故障處理的目標、思路、步驟、基礎設施。

本文是依據平時經歷的生產故障排查和處理,總結一些膚淺的方法論,以求共同探討,共同提高,歡迎探討。

線上故障處理的目標

任何動物一旦掉進坑裡,明智的做法一定是:跳坑–>填坑–>避坑,線上故障處理的過程也一樣,優先順序從高到低,線上故障處理的目標如下:

跳坑

‘跳坑’——快速恢復線上服務,或者將對線上服務的影響降到最低。

線上服務的可用性決定著服務者的客戶利益,影響著公司的收益。一旦線上環境不可用,無法服務使用者,給公司/團隊帶來經濟利益損失的同時,更為嚴重的會給公司/團隊帶來惡劣的名聲。所以一般公司都會對線上環境提出穩定性和可靠性的要求,這也是團隊乃至部門的kpi。為此,遇到生產故障後的第一要務是:恢復生產服務,即使不能完全恢復線上服務,也要想盡辦法將對線上服務的影響降到最低。

填坑

‘填坑’——找到問題原因,根本上解決問題。

在恢復線上服務,盡最大限度減掉對使用者/公司/團隊帶來的影響後,我們需要徹查問題,搞清楚故障發生的根本原因,從根本上解決問題。通常情況下,‘填坑’和‘跳坑’是同步在做的,完成‘填坑’也就意味中‘跳坑’成功,但是也有一些緊急情況下的特別‘跳坑’方法,比如重啟服務,或者服務降級/熔斷等等,實際並未在當時完成‘填坑’,而是先採取非常規手段‘跳坑’,之後再慢慢‘填坑’。

避坑

‘避坑’——舉一反三,消滅隱患。

找到了根本原因,解決了問題之後,我們需要舉一反三,以此及彼,想想在這個故障排查和處理過程中,那些環節存在弱點?那些流程/規範/制度需要優化?這類問題是否在其他系統或者團隊中也存在?通過這樣的反思和自我批評,形成一份線上事故報告,不斷完善流程,避免再次踩坑,也在團隊中交流經驗,共同提高。

線上故障處理的思路

依據線上故障處理的目標及目標的優先順序,線上排障的第一目標是恢復線上服務或者降低對線上服務的影響,關鍵點在於快速二字,在‘跳坑’-‘填坑’之後,再行回溯總結,以便‘避坑’。因此,可以將線上故障處理的步驟分為:

  1. 故障發現
  2. 故障定位
  3. 故障排除
  4. 故障回溯

其中前三步是‘跳坑’行為,後面一步包含了‘填坑’和‘避坑’。

上述步驟並不是說要從上到下順序進行,建議在不亂陣腳的情況下,並行去做,因為通常線上故障後會緊急啟動故障處理程式,運維、開發、測試、產品各個角色都會參與進來,這時候分工下去,並行去做,不斷彙總訊息,做出判斷,以求快速排障,恢復服務。這個思路類似於作業系統的fork/join設計思想,目的在於提高效率

在無法快速找到故障原因的時候,需要果斷跳過故障定位環節,直接進行故障排除,比如採用服務降級、伺服器擴容等手段,確保對線上服務降到最低且可控。等到線上服務’撐’過去之後,我們再慢慢定位故障原因,根本上解決問題。

下面我們會對這四個步驟進行詳細說明。

故障發現

線上故障一般可以通過如下幾種途徑傳遞到開發/運維人員手中,按照從上到下的順序,故障的嚴重程度依次變高。

  • 主動發現——可能是開發或者運維不經意間檢視生產環境的error日誌,或者例行檢查監控項時,看到了一些異常的現象,進而發現了故障;
  • 系統監控告警——通常包括cpu、記憶體、io、tcp連線數、disk、執行緒數、GC、連線池等各個伺服器指標異常,可能是伺服器出現了異常,但是業務還未受到大面積影響;
  • 業務監控告警——如使用者登入失敗率增加,訂單堆積量增大,則意味中系統的異常已經很嚴重,影響了業務處理;
  • 關聯絡統故障追溯——上游系統或者下游系統的故障處理郵件/電話追溯,可能和本系統有關係,而且情況已經變得很糟糕了,需要快速定位;
  • 生產事件上報——通常業務異常帶來的影響傳遞到使用者,再從使用者傳遞到客服人員,再到技術人員手裡,會存在一定時延,所以一旦有生產事件上報,這個時候嚴重性已經到了最高,技術人員的壓力也會增大,因為會有領導的關注,產品經理的詢問和催促,客戶人員的焦慮帶來的壓力。

上述途徑傳遞過來的資訊僅僅只是線上故障苗頭,並非一定就發生了大規模的線上故障,所以首先需要確認的是這是不是一次線上故障?還是隻是個例生產問題?是否和本系統有關係?一般來講:‘系統監控告警’和‘業務監控告警’的情況下,大部分都和本系統有關,且可能是線上故障;而‘主動發現’和‘生產事件上報’則需要做甄別,可以根據上報事件個數或者問題復現的方式來評估是否是大規模線上故障,或者跟蹤日誌資訊或者特定使用者問題追溯來確定。至於‘關聯絡統故障追溯’的情況,首先不要慌,先從巨集觀上確定本系統服務正常,一般可以檢查是否有伺服器監控報警,是否有業務監控報警等來確定,如果上游或者下游提供了日誌,可以通過日誌進行追蹤,從而確定本系統是否存在故障。

因此在得到一些線上故障苗頭之後,可以通過以下途徑確定是否是線上故障:業務監控告警、上報事件個數、問題重現、伺服器監控等。這些途徑可以並行進行,靈活組合,有時候一個手段就能確定,有時候需要組合多個手段予以判定

1

故障定位

一旦確定是線上故障後,我們需要快速定位故障點,找到問題原因,以便對症下藥,快速排除故障。

故障定位是一個不斷‘收集資訊–假設–驗證–嘗試’的迴圈過程,基本思路:拿到線上資訊,產生懷疑點,拿到更詳細的資訊,進行推理驗證,必要時刻,找到可行的驗證措施,進行可控的嘗試,或者在測試環境進行業務測試重現,效能測試重現。

可能存在的懷疑點有:

  • 新版本釋出有問題
  • 潛在的程式bug被激發,比如在訪問量暴增的情況下,併發bug被激發
  • 業務量暴漲
  • 遭遇攻擊,如活動期間羊毛黨刷積分等
  • 上游服務呼叫異常,如上游系統升級httpclient後,將長連線改為短連線
  • 下游服務異常,下游服務當機
  • 網路問題
  • 伺服器故障,如磁碟滿,記憶體爆掉等
  • 應用故障
  • 資料庫故障

為此,可以通過如下幾方面收集資訊,以便支撐你的懷疑點:

  • 最近新版本的釋出情況
  • 本服務的異常/error日誌
  • 本服務的呼叫量變化情況,是否存在暴漲?
  • 本服務的吞吐量,是否出現下降?
  • 本服務的時延,是否出現突然增大?
  • 伺服器TCP的連結情況,是否存在大量的CLOSE_WAIT?
  • 伺服器的cpu使用率,是否突然飆升?
  • 伺服器的disk,磁碟空間是否已經用完?
  • 伺服器的記憶體,記憶體是否爆掉?
  • 資料庫或者儲存是否掛掉?

很多故障並不是由於單一原因造成的,而是多個條件同時滿足時才出現的,所以,需要多收集資訊,綜合得到的資訊,產生懷疑點,快速推理和驗證,最後找到問題點,定位到故障。這個過程中可以集合大家的力量,並行去check各個點,並快速反饋資訊。

由於組合情況眾多,這裡只將明顯的故障定位場景列出,更多的需要總結歸納:

  • 釋出了最新版本,且故障最早出現時間在版本釋出之後,很大程度上時由於新版本釋出帶來的問題,可能是bug,也可能是部署出現問題;
  • 未釋出新版本,業務訪問量猛增,服務時延增大,吞吐量先上升後下降,到最後服務直接不可用,可能原因是:業務量暴漲/遭遇攻擊/上游服務異常呼叫;
  • 未釋出新版本,部分服務失敗,服務錯誤率增加,業務訪問量增加,可能原因是業務訪問量增大激發了潛在的併發bug,或者出現了io瓶頸等;
  • 業務訪問量並未增加,但是服務時延下降,吞吐量下降,服務錯誤率增加,且伺服器TCP的CLOSE_WAIT增大,這時候需要懷疑下游依賴服務是否異常。
  • 業務訪問量並未增加,服務大範圍不可用,日誌中出現大量資料庫錯,很明顯資料庫可能出現問題,或者應用的資料庫連線池出現問題。

不一而足,需要逐步積累。下圖是對上面描述的總結。

1

故障定位的初期,一般會先通過郵件+電話的方式進行溝通,如果幾分鐘之後事態變糟糕,且沒有眉目,則需要緊急啟動會議形式的聯合排障,所有相關人員需要放下手頭事情,集中到一個特定會議室進行聯合排障。這樣的好處也在於能夠迅速共享資訊,快速做出決策。聯合排障人員通常會包括:開發、運維、測試、產品,主力應當是開發和運維,測試和產品需要幫忙快速確認一些東西,如復現問題,或者確認業務邏輯等。

從上面可以看到,故障定位過程中,追求‘快速’二字,為此多項事情是並行去做的。為了避免出現群龍無首的慌亂局面,需要有一個主心骨坐鎮,把握排障的方向並最終做出決策,這個人是master,需要冷靜沉著,且要能排程儘可能多的資源,所以技術leader或者運維leader會比較合適。這個類似於分散式系統的設計思路。

另外,在故障定位過程中,獲得的線上一線資訊需要通過某種形式記錄下來,郵件往來是一種比較好的方式,在完成通訊和資訊共享的基礎上,也無形中保留了現場。其他的資訊包括:error log,dump檔案,伺服器各個指標的狀態值等等。

故障排除

一旦定位到故障原因,對症下藥地排除故障就不是什麼難事了,具體的措施可以參考下圖中的總結:

1

這裡需要特別指出一個特別的場景:無法定位故障的情況下如何迅速排除故障。

很多時候無法及時找到故障原因,必須直接進入故障排除,這時候的思路就在於:盡最大可能降低線上服務影響了。可以採用的手段有如下幾項:

  • 服務降級——定位到某些服務有異常,但不清楚異常出現的原因,直接將這些服務降級,確保其他服務不受影響;
  • 服務緊急擴容——無法定位到是哪些服務造成的,伺服器資源彪升,扛不住壓力時,緊急擴容伺服器;比如惡意攻擊、營銷活動,秒殺等場景帶來的突發情況;
  • 回退版本——有新版本釋出,但是不能迅速確定是否和新版本有關係,先做版本回退,確保線上服務回到上一個穩定版本。

還是那句話,故障排除的原則是:確保線上服務快速恢復,不能完全恢復的情況下,確保線上服務儘可能少地受到影響。

故障回溯

故障回溯的目的是在故障排除後,冷靜地回溯整個線上故障的發現/定位/排除過程,找出流程中/架構中/制度中的缺陷,並將該缺陷消滅掉,同時推而廣之到其他系統。在‘跳坑’–‘填坑’之後,我們需要通過故障回溯的過程達到‘避坑’的效果,即要保證自己能‘避坑’,也保證團隊/公司能夠避開類似的坑。

故障回溯的過程,因人因團隊而異,最重要的是要有嚴肅的‘形式’和最終的產出物。之所以提到嚴肅的‘形式’,是因為線上故障無小事,一定要讓大家牢記在心。

至於如何達到‘嚴肅’,可以參考如下形式:

  • 可以和kpi掛鉤。慎用,可能會傷害到技術人員的心,造成‘懶政’現象——“多幹多出事,少幹少出事”出現;
  • 可以實施追責制度。同上;
  • 還可以進行郵件或者會議形式的討論,廣而告之。

總之,故障回溯的最終的目標不是為了追責,更重要的是讓大家長記性,避免後續再次踩坑,而且線上故障報告的產出物一定要有,一方面是經驗的積累,便於分享,另一方面也讓當事人擼清楚事件過程,吃一塹長一智。

可以參考的一個流程如下:

1

線上故障處理的‘後勤保障’

前面談了線上故障處理的目標、思路和步驟,回過頭來看下,要快速準確地定位和排除線上故障,需要很多基礎設施支撐,它們是線上故障處理的‘後勤保障’。結合上面的內容歸納總結如下:

完善的監控/告警體系

通過告警,能讓我們迅速知道自己的服務出了問題,通過監控可以從時間維度進行對比分析,找到可疑點,進而定位故障。

監控通常分為:

  • 伺服器監控——針對作業系統資源使用情況(比如cpu使用率、內容使用率、磁碟空間、io、network等),容器健康程度(記憶體使用情況、執行緒數、GC情況等),application健康程度的(服務的可訪問性等);
  • 服務監控——包括吞吐量、時延等,這些指標至少包括:最大值、平均值,通過這些指標可以判斷單個服務的變化情況和健康程度;
  • 業務監控——包括訪問量、錯誤率等,一個業務場景往往會包含多個服務呼叫,因此通過業務監控,可以發現一些關聯問題。

告警方面,需要根據實際情況和業務場景進行閾值設定,告警閾值的設定是一個動態調整的過程。

監控系統最基本的需要保證:按照時間序列進行統計、對比。

完善的日誌trace體系

線上上故障處理過程中,日誌尤其重要,通過日誌能夠定位到問題或者bug細節。在分散式架構的系統中,多例項的部署導致日誌分散在多臺機器上,靠人肉檢視耗時費力,效率低下;另一方面,業務發展壯大後,業務系統越來越多,系統間依賴越來越多,各個業務系統的日誌需要通過唯一的標識串聯起來,否則會出現資訊斷層的問題,日誌變得無用。所以完善的日誌trace系統非常必要。

日誌trace體系的幾個關鍵點:

  • 有唯一的標識串聯上下游系統日誌
  • 能自動收集分散式應用日誌
  • 日誌收集時延不能超過10分鐘(具體時間試實際情況而定,如果時延太長,日誌沒有多大意義)
  • 支援多種形式的查詢/過濾/統計等
  • 可以看到時間序列上的變化趨勢

推薦使用開源的日誌架構:logstash+elasticsearch+kibana。

完善的故障處理機制

線上故障處理的要點在於快速,所以需要有完善便捷的事件流轉機制和故障處理機制來保證:生產事件能快速推送到相關責任人進行聯合排除,保證事件排查過程中快速共享資訊,快速完成決策。

對於事件上報,一般的公司會有專用的通道給到一線客服人員,客戶人員填報工單,上報事件,關鍵點在於事件處理中擔任‘路由’角色的人員,他需要對業務系統比較熟悉,對於上報的問題能快速確定相關的業務系統和負責人,並通知到對方,這個角色既要熟知業務,也要熟知系統架構和組織架構,這個角色一般會交由專門人員處理,稱之為‘二線’人員,或者由運維人員兼職。

排查生產事件/故障時,推薦進行集中版本,便於快速共享資訊,同時需要有一個master,以便把握大的方向,並快速完成決策。

總結

以上,對線上故障處理的目標、思路、步驟及基礎設施進行了討論,先總結如下:

  • 線上排障的第一目標是恢復線上服務或者降低對線上服務的影響,關鍵點在於快速二字,在‘跳坑’-‘填坑’之後,需要總結以便‘避坑’。
  • 一切的流程或者手段都是為‘快速’二字服務的,所以線上故障是最高優先順序的任務,任何人需要第一時間予以響應;同時,儘早地反饋故障問題,儘早地集結各個角色,群策群力地進行排障值得提倡;這個過程中,需要有一位有‘威望’的master坐鎮,主持大局;在保證有序推進的情況下,儘可能地並行地收集資訊,進行嘗試。這個有點分散式架構的味道了,master坐鎮,slave並行幹活,提高效率。
  • 必須要有一個‘嚴肅’的形式讓當事人及旁觀者‘吃一塹長一智’,線上故障處理報告是必須的產出物。
  • 為了更加高效的處理線上故障,需要有完善的基礎設施支撐:監控/告警體系、日誌trace體系、事件流轉機制。

對於線上排障的流程整理了一個大圖,如下:

1

案例

線上故障處理——大量異常堆疊日誌輸出影響服務可用性

參考資料

本文中部分觀點來源於goole出版的《Google SRE》一書,這本書中有很多實用的且經過實踐證明了的詳盡的例子,該書的讀書筆記可參考:《Google SRE讀後感

相關文章