遇到線上事故,應(yīng)該如何處理?

在做系統(tǒng)的開發(fā)過程中,大家都會(huì)遇到線上的事故這個(gè)問題。即使再牛的工程師也沒有辦法保證所開發(fā)的系統(tǒng)完全沒有bug。而且事故的原因也不僅僅是系統(tǒng)bug,可能還有各方面的原因,有軟件層面的、有硬件層面的、有網(wǎng)絡(luò)的等等。

一個(gè)高級(jí)別的架構(gòu)師與一般的工程師的主要區(qū)別就在于實(shí)現(xiàn)業(yè)務(wù)功能的同時(shí),在系統(tǒng)健壯性、穩(wěn)定性方面設(shè)計(jì)的差異??赡墚?dāng)一切正常的時(shí)候,普通程序員開發(fā)的系統(tǒng)也能夠滿足業(yè)務(wù)的場(chǎng)景,但是一旦發(fā)生異常的時(shí)候,這時(shí)候普通程序員與架構(gòu)師設(shè)計(jì)的系統(tǒng)的區(qū)別就體現(xiàn)出來了。普通程序員設(shè)計(jì)的系統(tǒng)可能出現(xiàn)一點(diǎn)異常的時(shí)候整個(gè)系統(tǒng)就無法使用了,高級(jí)別的架構(gòu)師在設(shè)計(jì)系統(tǒng)的時(shí)候會(huì)充分考慮各種異常的場(chǎng)景以及降級(jí)措施,當(dāng)系統(tǒng)出現(xiàn)問題的時(shí)候保證系統(tǒng)能夠正常穩(wěn)定運(yùn)行。

線上事故既然不可避免,一旦發(fā)生現(xiàn)場(chǎng)事故之后如何進(jìn)行處理呢?

同樣的一個(gè)線上的事故,如果處理的方法不一樣那么導(dǎo)致的結(jié)果也會(huì)完全不一樣。在沒有任何方法論的時(shí)候很多人上去同時(shí)處理,大家都很積極,各抒己見,爭(zhēng)論不休,這種無序的狀態(tài)反而導(dǎo)致處理問題的效率降低。在處理線上問題過程中要爭(zhēng)分奪秒,因?yàn)槊柯环昼?,線上就多一分鐘的損失。

但是如果有一套有效的分工與方法之后,可能分鐘級(jí)別就可以把線上的事故解決掉,大大提升了解決問題的效率。我們?cè)谶@方面也吃過很多虧,很多線上的事故,其實(shí)并不是很復(fù)雜,但是在事故處理過程中組織的不是很好,導(dǎo)致處理問題耗時(shí)較長(zhǎng)。

經(jīng)過我們對(duì)之前事故的過程不斷復(fù)盤,總結(jié)出一套處理線上事故的方法論,可能還不是很完善,但至少大家思路統(tǒng)一,不完善的地方后續(xù)可以繼續(xù)迭代完善。避免出現(xiàn)思路太發(fā)散、毫無章法導(dǎo)致嚴(yán)重拖長(zhǎng)了解決問題的時(shí)間,從無序變?yōu)橛行颉?/p>

主要分為下面五點(diǎn):

要有一個(gè)事故的上報(bào)機(jī)制。

事故發(fā)生之后,要立刻評(píng)估影響范圍。

要有快速定位問題的能力。

“止損第一”,先通過最快的方式恢復(fù)線上的生產(chǎn),可能是臨時(shí)方案或者是終極解決方案。

進(jìn)行事故的復(fù)盤與總結(jié)。

下面針對(duì)這五點(diǎn)詳細(xì)的說一下,我們先來看事故的上報(bào)機(jī)制。

當(dāng)事故發(fā)生的時(shí)候可能有幾種渠道得到信息的來源。

客戶發(fā)現(xiàn)系統(tǒng)無法使用進(jìn)行投訴,這是最不友好的一種。

我們系統(tǒng)內(nèi)部的值班人員發(fā)現(xiàn)系統(tǒng)問題。

我們研發(fā)人員通過監(jiān)控自己發(fā)現(xiàn)問題。

當(dāng)無論是哪一種渠道得知事故發(fā)生之后,首先要進(jìn)行上報(bào)。上報(bào)到小組leader或者是專門的事故處理群里,讓大家都知道這個(gè)信息。

我們之前也出現(xiàn)過事故發(fā)生后沒有及時(shí)上報(bào),只是幾個(gè)研發(fā)同學(xué)在緊急處理。但線上事故的有的時(shí)候可能會(huì)比較復(fù)雜,并不是表面看起來的那樣。比如,明明是A系統(tǒng)報(bào)了一個(gè)錯(cuò),但是根源可能不是A系統(tǒng),A系統(tǒng)可能是只是被影響,根源在B系統(tǒng)。這時(shí)候如果沒有將事故上報(bào)出來,僅僅是A系統(tǒng)的同學(xué)在處理,可能最后是花了很長(zhǎng)的時(shí)間最后定位不是A系統(tǒng)的問題,需要B系統(tǒng)的人進(jìn)來處理,這個(gè)時(shí)候就白白浪費(fèi)了前面的寶貴時(shí)間。

所以事故發(fā)生后,無論事故的大小,第一步是要先有一個(gè)上報(bào)機(jī)制,讓所有人都知道線上系統(tǒng)發(fā)生了什么問題,大家一起進(jìn)行排查。

第二點(diǎn)是評(píng)估事故的影響范圍。

事故的處理就像一場(chǎng)戰(zhàn)役一樣。你首先要知道這是一場(chǎng)什么級(jí)別的戰(zhàn)役。是小規(guī)模的沖突?還是局部戰(zhàn)役?還是全局的戰(zhàn)役?不同級(jí)別的戰(zhàn)役,處理的方式不同。

所以在著手處理事故之前,我們要先快速的評(píng)估出來事故的影響范圍是什么?

這里有兩點(diǎn)要注意,第一是事故發(fā)生的時(shí)候尤其重大事故發(fā)生的時(shí)候大家可能會(huì)比較慌亂。每個(gè)人都在出謀劃策,每個(gè)人都在評(píng)估范圍,各抒己見,這時(shí)候噪音比較多。

所以在處理事故的時(shí)候,第一點(diǎn)要注意的是必須有一個(gè)明確的主要負(fù)責(zé)人或者是協(xié)調(diào)人,大家聽這個(gè)人的統(tǒng)一號(hào)令。

另外一點(diǎn)評(píng)估影響范圍這個(gè)事情,要由專人或者是專業(yè)的角色來做,不需要每個(gè)人都上來評(píng)估。我們這邊是由測(cè)試的同學(xué)來負(fù)責(zé)評(píng)估范圍。也就是當(dāng)事故發(fā)生的時(shí)候。測(cè)試同學(xué)首要的職責(zé)就是評(píng)估整個(gè)系統(tǒng)影響范圍是什么,給出事故的級(jí)別。我們事前會(huì)將事故定義好不同的級(jí)別,根據(jù)測(cè)試同學(xué)評(píng)估出來的影響范圍來采取不同級(jí)別的響應(yīng)措施。

第三點(diǎn)就是如何快速的定位問題。

測(cè)試同學(xué)在做范圍評(píng)估的同時(shí),相關(guān)的研發(fā)、運(yùn)維同學(xué)就要開始進(jìn)行定位問題。

定位問題也有幾個(gè)主要的有效手段。

第一個(gè)手段是通過監(jiān)控或者是告警來判斷出錯(cuò)的系統(tǒng)點(diǎn)在哪里。讓研發(fā)人員有一個(gè)大體的范圍。

第二點(diǎn)是日志。研發(fā)人員在得知一個(gè)大體的范圍之后,大概知道是哪一個(gè)模塊可能出現(xiàn)了問題,下一步就需要通過日志來詳細(xì)確認(rèn)是否是這個(gè)地方出了問題。

這里要注意的是日志在開發(fā)的過程中一定要打全,尤其是關(guān)鍵的路徑,一定要日志信息,對(duì)外的接口調(diào)用也一定要有日志信息。經(jīng)常出現(xiàn)在定位過程中發(fā)現(xiàn)關(guān)鍵環(huán)節(jié)沒有打日志,不清楚到底是系統(tǒng)的內(nèi)部流程問題還是對(duì)外調(diào)用的問題。一旦發(fā)生這種情況,那么將會(huì)大大的降低定位問題的效率。

第三點(diǎn)是定位問題時(shí)大家的“意識(shí)”問題。一旦出現(xiàn)線上事故,這個(gè)時(shí)候大家不要出現(xiàn)相互甩鍋的情況。擔(dān)心一旦是自己的問題,后續(xù)是否會(huì)有問責(zé)的問題。經(jīng)常遇到的情況是,大家默認(rèn)的態(tài)度就是,我的系統(tǒng)沒問題,如果你說我的系統(tǒng)有問題,請(qǐng)你給出證明。如果有這種意識(shí),那么也會(huì)影響解決問題的實(shí)效。因?yàn)樵谖覀冞@種分布式微服務(wù)的架構(gòu)中,某個(gè)環(huán)節(jié)出了問題,它會(huì)對(duì)各個(gè)環(huán)節(jié)的都有影響,產(chǎn)生連鎖反應(yīng)。就像上面的例子一樣,表面看起來是用戶系統(tǒng)出了問題,但其實(shí)用戶系統(tǒng)調(diào)用了緩存組件,可能是緩存組件出了問題。但緩存組件又部署在虛擬機(jī)上,也有可能是虛擬基礎(chǔ)的問題。虛擬機(jī)之間的通信需要網(wǎng)絡(luò),那最終也有可能是網(wǎng)絡(luò)出了問題。所以一旦用戶反饋用戶系統(tǒng)不能用,如果僅僅是用戶系統(tǒng)的研發(fā)在定位問題,可能是花了半個(gè)小時(shí)的時(shí)間,最后確定不是用戶系統(tǒng)的問題,是緩存組件的問題。緩存組件的研發(fā)又花了10分鐘,定位說不是緩存組件的問題,是虛擬機(jī)的問題。以此類推,運(yùn)維同學(xué)可能又花了10分鐘,最后定位出來是網(wǎng)絡(luò)的問題。最終可能運(yùn)維只需要調(diào)整一個(gè)網(wǎng)絡(luò)策略的配置就可以解決問題。但是整個(gè)過程花了近一個(gè)小時(shí)的時(shí)間。所以在定位問題的時(shí)候,各個(gè)部門的協(xié)調(diào)解決問題的意識(shí)也非常的重要。出現(xiàn)問題之后,首先要排查自己有沒有問題,要先證明自己沒有出問題,而不是等著別人證明你有問題。只有當(dāng)大家同時(shí)動(dòng)起來,才可能從各個(gè)角度分析問題,協(xié)同起來,快速的將問題定位出來。

最后的一點(diǎn)就是要會(huì)抓包。很多問題都是直觀但表現(xiàn)在客戶端上某個(gè)頁(yè)面打不開,某個(gè)流程會(huì)報(bào)錯(cuò)。那么具體是服務(wù)端哪一個(gè)接口返回出錯(cuò)了呢?當(dāng)然一種方式是通過監(jiān)控來看,這是一種方式,另外還有一種更直觀更快速的方式就是通過前端的抓包來快速定位問題點(diǎn)。通過抓包可以判斷是域名無法通,還是域名通了之后,后端的請(qǐng)求返回出錯(cuò)以及是具體哪一個(gè)請(qǐng)求出錯(cuò),能夠大大的縮小定位的范圍。

第四點(diǎn)就是當(dāng)問題定位出來之后,那么下一步就是怎么樣快速的恢復(fù)生產(chǎn)。

解決問題大體上分為兩種,一種是臨時(shí)解決方案,一種是終極解決方案。

在處理事故過程中,首先要有一個(gè)原則是“優(yōu)先止損”。因?yàn)槭鹿室坏┌l(fā)生,一定會(huì)對(duì)用戶端的體驗(yàn)或者公司有損失,所以解決事故的第一原則是要首先減少這種損失。

根據(jù)這一個(gè)原則,那么在解決事故的過程中,最重要的就是要快速解決問題。當(dāng)問題定位到之后,有的時(shí)候要根本解決這個(gè)問題,可能會(huì)要花費(fèi)比較長(zhǎng)的時(shí)間,需要修改代碼,需要重新發(fā)布等等。但用戶是不可能等這么長(zhǎng)時(shí)間的,那這時(shí)候要看有沒有臨時(shí)的解決方案,能夠快速的先解決問題,等線上的問題解決之后再花時(shí)間去從根本上解決這個(gè)問題。

這里舉兩個(gè)例子,正好是前段時(shí)間線上發(fā)生的真實(shí)事故。

第一個(gè)是前段時(shí)間評(píng)價(jià)系統(tǒng)突然無法評(píng)價(jià)。用戶提交評(píng)價(jià)的時(shí)候會(huì)報(bào)錯(cuò),經(jīng)過研發(fā)與dba的定位之后,發(fā)現(xiàn)是評(píng)價(jià)系統(tǒng)的數(shù)據(jù)庫(kù)鏈接數(shù)滿了,導(dǎo)致數(shù)據(jù)庫(kù)達(dá)到了瓶頸,無法進(jìn)行響應(yīng)。那么為什么數(shù)據(jù)庫(kù)鏈接會(huì)突然之間暴漲?這個(gè)原因其實(shí)還沒有找到,但是找到了為什么評(píng)價(jià)系統(tǒng)無法寫入評(píng)論數(shù)據(jù)的原因,就是數(shù)據(jù)庫(kù)的鏈接數(shù)已經(jīng)滿了。

這個(gè)時(shí)候一種方式是我們要找出根本的原因,到底是程序的問題還是數(shù)據(jù)庫(kù)的問題導(dǎo)致了鏈接數(shù)一直沒有釋放,在不斷的增加,但是這個(gè)過程會(huì)比較耗時(shí),可能短時(shí)間無法找出真正的原因。另外一種方案就是將進(jìn)程數(shù)量調(diào)整下或者數(shù)據(jù)庫(kù)重啟,先將鏈接數(shù)釋放下來解決當(dāng)前的線上問題。我們的選擇首先是將進(jìn)服務(wù)進(jìn)程數(shù)量調(diào)整,看看是否會(huì)降低鏈接數(shù)。當(dāng)服務(wù)的進(jìn)程都調(diào)整后,仍然沒有降低鏈接數(shù)。最后我們采取了重啟數(shù)據(jù)庫(kù)的方式,重啟數(shù)據(jù)庫(kù)之后鏈接數(shù)果然降下來了,這時(shí)候系統(tǒng)就已經(jīng)恢復(fù)了,線上可以正常的進(jìn)行評(píng)價(jià)的操作了。

但是為什么會(huì)導(dǎo)致數(shù)據(jù)庫(kù)的鏈接數(shù)突然之間爆漲這個(gè)原因還沒有找到。我們后面又開了專題的分析會(huì)去排查,但這個(gè)時(shí)候的時(shí)間壓力就沒有那么大,可以靜下心冷靜的去分析復(fù)盤這個(gè)問題的。

另外一個(gè)例子是我們前兩天在進(jìn)行訂單中間層的壓測(cè)。壓測(cè)之后導(dǎo)致訂單中間層出現(xiàn)了異常,APP上查看我的訂單詳情以及訂單列表打不開。

這時(shí)候通過研發(fā)跟測(cè)試的快速定位,發(fā)現(xiàn)是訂單的中間層沒有響應(yīng),或者是響應(yīng)速度已經(jīng)非常慢了,所以導(dǎo)致正常的用戶也打不開。但至于中間層為什么會(huì)響應(yīng)非常慢,這個(gè)原因還沒有找到。壓測(cè)的流量已經(jīng)停止了,但是系統(tǒng)還是無法使用。本著快速止損原則,我們采取將中間層回退到老版本的方案。在做這個(gè)新的訂單中間層之前我們就已經(jīng)有預(yù)案,如果新的中間層出現(xiàn)問題,我們會(huì)有方案快速的回退到老版本。通過這個(gè)預(yù)案,我們很快的將線上的業(yè)務(wù)問題解決掉了??梢哉5脑贏PP上打開訂單列表以及訂單詳情了。然后我們又花時(shí)間去定位為什么當(dāng)時(shí)壓測(cè)之后導(dǎo)致新的中間層打不開。這里有一點(diǎn)很重要,就是凡事要有PLAN B,也就是預(yù)案。每次發(fā)布新系統(tǒng)、新功能都要有預(yù)案,一旦這次發(fā)布失敗需要怎么做,怎么樣去解決這個(gè)問題。

最后一步就是事故的復(fù)盤總結(jié)。

事故的復(fù)盤總結(jié),要問自己5個(gè)問題。

為什么會(huì)發(fā)生這個(gè)事故?為什么沒有測(cè)試到這個(gè)線上的問題?為什么沒有第一時(shí)間系統(tǒng)檢測(cè)到這個(gè)事故?為什么會(huì)花這么長(zhǎng)時(shí)間解決問題?下一次該如何避免類似的問題?

將這5個(gè)問題一一回答了,才達(dá)到了真正的復(fù)盤的目的。事故復(fù)盤還有另外一點(diǎn)要注意的,就是對(duì)于復(fù)盤中提出的后續(xù)優(yōu)化的策略,要有一個(gè)明確的時(shí)間點(diǎn)以及具體的優(yōu)化方案,要有相關(guān)的同學(xué)進(jìn)行跟進(jìn),是否真正落實(shí)到位的。

因?yàn)橛行﹥?yōu)化策略是一個(gè)比較大的動(dòng)作,可能需要相對(duì)較長(zhǎng)的時(shí)間去做,如果沒有人跟進(jìn)的話,這個(gè)事情可能后面就會(huì)不了了之,后面可能又會(huì)因?yàn)檫@個(gè)事情有沒有做而發(fā)生類似的問題,所以事故的復(fù)盤要閉環(huán),要先找出問題的本質(zhì)原因,然后怎么去解決這個(gè)問題,什么時(shí)間去解決,這樣才是真正的將問題閉環(huán)掉了,避免同一個(gè)問題再次發(fā)生。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容