系統壞了,不要慌,參考如下措施

安全劍客發表於2020-08-01
導讀 作為程式設計師,相信有一件事是大家最不想見到的。那就是,線上執行的系統出現了技術性故障。(特別還是週末你正在外面happy的時候:D)

系統壞了,不要慌,參考如下措施系統壞了,不要慌,參考如下措施

處理這類事情特別能體現一個人的綜合能力。因為它會涉及到抗壓能力、對外的溝通能力,以及排查問題所需的技術能力等等多個方面。如果你還沒機會成為核心開發,其實很少會有這樣充滿壓力的經歷。因為在這個情況下處理事情其實是很慌的,畢竟所有使用系統的人以及他們的老闆、你的上級、你的老闆等等無數雙眼睛都在盯著這件事情。

我還記得有一年雙11,我作為“首席問題處理官”正在緊急處理伺服器扛不住壓力的問題,老闆默默走到我身後問到“什麼問題啊?什麼時候好?”。你腦補一下這畫面,想象一下看看。

只要你接下去還會繼續從事程式設計師這個職業,我想這樣的場景你總歸會有機會遇到的。因為一個著名的定律——墨菲定律。墨菲定律:凡是可能出錯的事就一定會出錯。如果沒有一個清晰的應對思路,那麼一旦發生線上問題就會像熱鍋上的螞蟻一樣,急得團團轉,像無頭蒼蠅一樣到處亂撞(試)。

所以,我這次就想分享一些我多年作為“首席問題處理官”所總結下來的經驗。這可是承載了我N多汗水和腦細胞的經驗~

在日常的專案開發迭代過程中我們遇到一個bug,大家的處理過程幾乎是一樣的:定位bug -> 解決bug。可能少部分人在解決bug之後會有一個思考、覆盤,看看是否有類似bug的地方,一併處理掉。

這個“定位 -> 解決 -> 覆盤”的過程也同樣適用於線上問題的處理。但是必然不僅僅如此。俗話說,解決一個問題最難的地方不是解決的過程,而是定位的過程。所以,針對線上問題我們等不起定位問題所花費的時間,因此要將「恢復」系統正常使用放在最首要的位置。所以,這個過程就變成了:“恢復 -> 定位 -> 解決 -> 覆盤”。

這裡多說一句,有一部分人的觀點認為,將恢復系統作為首要目標,應當包括犧牲保留現場的動作,因為這個動作可能也需要耗費數分鐘才行。我對這個觀點持反對意見。理由是,解決問題的時長的確是一個很重要的指標,但是問題既然已經發生,如果由於沒有保留現場導致後續沒有排查到根源,導致下次該問題再次出現,到時候場面將會更加難看。所以我對這事的觀點是,保留現場最重要。因此,這個過程又變成了:“保留現場 -> 恢復 -> 定位 -> 解決 -> 覆盤”。

當然了,保留現場也不是說非得面面俱到,花很多時間。用最快的方式保留你當下所能想到的所有相關線索的地方即可。如果事後還是由於線索不足導致未能排查到根本原因,那隻能說經驗不足,考慮一下以後需要多保留哪些現場資料才行。好了,確定了這5個步驟,那麼具體每個步驟可以做些什麼呢?我來一個個說。

/01 保留現場/

保留現場最最最重要的一件事是儲存異常程式的dump檔案。有了它,你就可以擺脫盲人摸象式的分析問題,可以快速定位問題的發源地。

我用了三個“最”來強調它的重要性。如果你還沒掌握它,那麼後面我提到的東西都先放一放,先去掌握它。

另外,如果系統的監控體系並不完備的話,還需要將問題發生時,作業系統、各第三方元件自帶的監控資料快速地透過截圖儲存下來。

儲存監控資料的時候要特別留意一下網路相關的資料。如果發現網路相關的資料有異常,那麼再把當下的網路連線情況透過 儲存下來。因為相對來說,網路出現問題的機率遠遠大於硬體,不管是程式導致的還是其他原因。規模越大的系統,越是如此。

/02 恢復/

恢復系統訪問有很多方法。首先不得不提到一個適用於80%情況的神技了——重啟。沒錯,根據多年的經驗來看這招的確在大多數情況下很有效。也正因為屢試不爽,所以很多人習慣性地會在第一時間去重啟,導致現場忘記儲存並受到破壞。重啟也分兩種,強制重啟和自然重啟。當然優先考慮自然重啟,這樣能避免產生一些意料之外的髒資料。但是如果是系統出現資源耗用異常的話,就不要傻傻地等自然重啟了,只能強制重啟(kill掉程式)。

第二種常見的方法是「回滾」。當然它的前提條件是你判斷下來問題的出現是由於最近一次釋出。否則盲目的回滾不但起不到作用,還會越弄越亂,特別在分散式系統中。因為在分散式系統中,一旦上下游耦合的地方出現對接不上,輕則報錯,重則出現大量的異常資料,夠你後續折騰好久的。

第三種方法是「降級」。暫停出問題的模組,停止服務。當然,這個動作需要和業務方做好溝通,是否單獨降級某個模組會導致業務不完整之類的問題。

第四種方法是「限流」或者「擴容」。如果你發現是系統扛不住突增的流量,如果有條件的話可以快速擴容幾臺機器和程式。如果沒法擴容的話可以選擇限流,將一定百分比的請求直接拒絕服務。畢竟所有無法提供服務和部分無法提供服務相比,肯定還是後者划算。

還有一些比較小眾的方法是「切到備機」、「故障隔離」等,這裡就不展開了。它們對環境、條件的要求更多一些。有時候可能系統並未恢復到完全正常的狀態,比如,讀取資料是OK了,但是某些操作寫入資料到時候還是有問題。在這樣的情況下,不要著急定位問題,還是先盡最大努力恢復到最大程度的可用狀態再進行下一步的動作,畢竟使用者第一嘛。

/03 定位/

關於定位問題,如果有dump檔案的話最方便了,透過dump檔案分析工具來分析dump檔案就可以快速定位到出問題的程式碼行,特別是程式阻塞、記憶體溢位、cpu100%之類明顯是程式本身的問題。

不同的語言有不同的dump分析工具,可以自行網上搜一下教程。最終目的就是定位到異常點的堆疊資訊,有了它就相當於直接把問題程式碼出現在哪裡都給定位到了。

如果說分析dump檔案是跳過抽絲剝繭的步驟,直擊要害的話。透過監控資料、日誌層層分析是個慢活。但是如果缺失dump檔案或者從dump檔案從未能分析出問題的情況下,也只能選擇後者。

我們在看日誌、監控資料的時候一定要有關聯起來看的意識,而不能僅僅在單個維度上看。因為有時候你在單個維度上看到的資料像是正常的,但是你關聯起來看就不一定了。比如,tcp連線數降低了一半,但是記憶體反而漲了100%,為什麼?這裡面可能就藏著故障的線索。

/04 解決/

定位到了問題,解決起來就很簡單了。該改程式碼的改程式碼,該改配置的改配置檔案。這裡就不多說了,畢竟情況太多,大家遇到的可能都不太一樣。

/05 覆盤/

大家都知道覆盤的好處,但是真正做覆盤的人真不多。如果你不知道從何下手來做覆盤的話,不妨從以下幾個問題入手。

1.這次故障原因是什麼?

2.是否有更快的方式在當時來恢復業務?

3.如何避免再出類似故障?

4.當前系統中是否還有類似的潛在風險?

如果你能回答這些問題,我覺得這個覆盤就很到位了,剩下的就是執行。

當然了,不管如何優秀的處理故障,最理想的還是不要發生故障。所以我們需要在前期做更多的準備。

/06 瞭解你的程式/

我們很多人瞭解自己負責的程式只有透過coding這一種途徑。除非該程式是個單體應用,否則這樣的方式是遠遠不夠的。

我建議你按照以下清單去了解你的程式:

1.程式包含有哪些模組,對應使用者是哪些?哪些是核心模組,哪些是可以“棄車保帥”的?

2.多個模組/系統間如何流轉的?(儘量畫一個流程圖,加深記憶)

3.依賴了哪些中介軟體,誰負責維護他們?

4.依賴了哪些其他的程式,強依賴還是弱依賴,誰負責維護他們?

5.依賴的儲存、訊息佇列背後又依賴了哪些儲存,儲存運維負責人是誰?

6.線上的程式部署在什麼環境。你是否有條件獨立進行部署並調優?

/07 做好監控/

大多數的故障不是突然發生,而是有一個逐漸積累的過程,直到爆發。所以監控的價值不僅僅是看看資料那麼簡單,對於異常識別特別有幫助。

一般監控分兩個維度,系統維度和業務維度。監控指標分為三層,「環境指標」、「程式指標」、「業務指標」。具體怎麼做我在之前的文章《分散式系統關注點——360°的全方位監控》有具體說明,這裡就不贅述了。

如果是分散式系統,還可以搭建一個請求鏈路跟蹤系統。有很多成熟的現成解決方案,CAT、SkyWalking、Zipkin、Pinpoint等等。

多說一句,我們在做監控預警的時候,除了設定閾值還要關注一下波動率。比如,某項資源日常使用率20%,除了設定超過80%的閾值進行預警之外,在它產生波動幅度100%(使用率40%)以上的時候也需要預警,提前讓人關注。否則一旦以一個較快的速度增長到80%之後,留給你在故障爆發前消滅它的機會就非常渺茫了。

另外,針對常見的故障預設幾套故障響應方案,以及進行定期的故障演練(一般上了一定規模的公司或者處於擴張期的公司才會考慮)可以讓團隊面對線上故障的時候更加地遊刃有餘。

假如你不幸成為了線上故障的解決者,如果上級不在旁邊的話,需要定時向上級彙報問題處理情況,以便TA瞭解問題的嚴重程度、修復進度並作出決策。

反正就算你不上報,遲早也會被催。與其被動的被催,不如主動上報。

原文來自:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2708673/,如需轉載,請註明出處,否則將追究法律責任。

相關文章