1. 說(shuō)之前由于業(yè)務(wù)應(yīng)用 bug(本身或引入第三方庫(kù))、環(huán)境原因、硬件問(wèn)題等原因,線上服務(wù)出現(xiàn)故障 / 問(wèn)題幾乎不可避免。例如,常見(jiàn)的現(xiàn)象包括請(qǐng)求超時(shí)、用戶明顯感受到系統(tǒng)發(fā)生卡頓等等。 作為一個(gè)合格的研發(fā)人員(技術(shù)人員),不僅要能寫(xiě)得一手好代碼,掌握如何排查問(wèn)題技巧也是研發(fā)人進(jìn)階必須掌握的實(shí)戰(zhàn)技能。這里提到的排查問(wèn)題不僅僅是在Coding的過(guò)程中Debug,還包括測(cè)試階段、線上發(fā)布階段問(wèn)題的排查。特別是在生產(chǎn)環(huán)境中,一般是沒(méi)辦法或很難進(jìn)行Debug操作的。 而通過(guò)掌握服務(wù)線上問(wèn)題排查思路并能夠熟練排查問(wèn)題常用工具 / 命令 / 平臺(tái)來(lái)獲取運(yùn)行時(shí)的具體情況,這些運(yùn)行時(shí)信息包括但不限于運(yùn)行日志、異常堆棧、堆使用情況、GC情況、JVM參數(shù)情況、線程情況等。 排查出問(wèn)題并找到根本原因加以解決,其實(shí)是一件很成就感的事情。曾經(jīng)有人問(wèn)過(guò)我:“你是怎么想到問(wèn)題出現(xiàn)在xxx的?又是怎么確認(rèn)根本原因是xxx的?”,我只能輕描淡寫(xiě)的回答:“靠經(jīng)驗(yàn)”,其實(shí)這里說(shuō)的“靠經(jīng)驗(yàn)”是很模糊的,一直以來(lái)大家可能都覺(jué)得排查問(wèn)題要靠經(jīng)驗(yàn),但是又說(shuō)不出具體通過(guò)什么樣的經(jīng)驗(yàn)排查出了問(wèn)題。而本質(zhì)上排查定位線上問(wèn)題是具有一定技巧或者說(shuō)是經(jīng)驗(yàn)規(guī)律的,排查者如果對(duì)業(yè)務(wù)系統(tǒng)了解得越深入,那么相對(duì)來(lái)說(shuō)定位也會(huì)容易一些。排查問(wèn)題的關(guān)鍵是什么?一句話總結(jié):給一個(gè)系統(tǒng)定位排查問(wèn)題的時(shí)候,知識(shí)、經(jīng)驗(yàn)是關(guān)鍵,數(shù)據(jù)是依據(jù),工具是運(yùn)用知識(shí)處理數(shù)據(jù)的手段!在此,我將結(jié)合自身經(jīng)歷、總結(jié),說(shuō)關(guān)于“問(wèn)題排查”的方法論,希望能與您產(chǎn)生更多的共鳴。
2. 有哪些常見(jiàn)問(wèn)題那我們經(jīng)常說(shuō)遇到這樣那樣的問(wèn)題,那到底有哪些問(wèn)題,問(wèn)題又集中在哪些方面?對(duì)于不同技術(shù)框架、語(yǔ)言族所可能引發(fā)的問(wèn)題也會(huì)存在很大的差異,但基本的套路排查思路都還是一致的,以Java為例。 所有 Java 服務(wù)的線上問(wèn)題從系統(tǒng)表象來(lái)看歸結(jié)起來(lái)總共有四方面:CPU、內(nèi)存、磁盤(pán)、網(wǎng)絡(luò)。例如 CPU 使用率峰值突然飚高、內(nèi)存溢出 (泄露)、磁盤(pán)滿了、網(wǎng)絡(luò)流量異常、FullGC 等等問(wèn)題。 基于這些現(xiàn)象我們可以將線上問(wèn)題分成兩大類(lèi): 系統(tǒng)異常、業(yè)務(wù)服務(wù)異常。 1. 系統(tǒng)異常常見(jiàn)的系統(tǒng)異?,F(xiàn)象包括: CPU 占用率過(guò)高、CPU 上下文切換頻率次數(shù)較高、磁盤(pán)滿了、磁盤(pán) I/O 過(guò)于頻繁、網(wǎng)絡(luò)流量異常 (連接數(shù)過(guò)多)、系統(tǒng)可用內(nèi)存長(zhǎng)期處于較低值 (導(dǎo)致 oom killer) 等等。 這些問(wèn)題如果是在Linux系統(tǒng)下可以通過(guò) top(cpu)、free(內(nèi)存)、df(磁盤(pán))、dstat(網(wǎng)絡(luò)流量)、pstack、vmstat、strace(底層系統(tǒng)調(diào)用) 等工具獲取系統(tǒng)異常現(xiàn)象數(shù)據(jù)。
2. 業(yè)務(wù)服務(wù)異常常見(jiàn)的業(yè)務(wù)服務(wù)異?,F(xiàn)象包括: PV 量過(guò)高、服務(wù)調(diào)用耗時(shí)異常、線程死鎖、多線程并發(fā)問(wèn)題、頻繁進(jìn)行 Full GC、異常安全攻擊掃描等。
3.問(wèn)題排查方法論一、排查問(wèn)題猶如破案排查線上問(wèn)題猶如警察破案一樣,是一個(gè)不停分析線索,推理的過(guò)程,但在準(zhǔn)備排查問(wèn)題之前,我們應(yīng)該明白三個(gè)認(rèn)知:
二、了解案情,評(píng)估大小先評(píng)估出這個(gè)問(wèn)題的影響范圍,是全網(wǎng),某些地區(qū),還是某條鏈路不可用的問(wèn)題,還是很多業(yè)務(wù)線都出現(xiàn)問(wèn)題,評(píng)估出案情的大小,到底是普通的民事案件,還是刑事案件。 三、理清線索,整理分析理清手頭已得到的信息或線索,比如監(jiān)控上有網(wǎng)絡(luò)報(bào)警,有用戶反饋無(wú)法訪問(wèn),有開(kāi)發(fā)人員反饋服務(wù)器有問(wèn)題,同時(shí)間段有做變更等等,盡量不要漏掉這些看似無(wú)關(guān)緊要的線索,把這些線索先整理下來(lái),后面一并分析。 推理的過(guò)程,就是根據(jù)已知線索,通過(guò)合理的想象、推斷得出一個(gè)唯一的結(jié)果。線索是整個(gè)推理過(guò)程的起點(diǎn),線索給出的好有不好、是否有錯(cuò)誤,直接會(huì)影響推理的質(zhì)量,因此是最基礎(chǔ)、也是最重要的一環(huán)。線索的梳理,最常犯錯(cuò)誤就是信息不足,主觀臆斷。 其中整理分析過(guò)程中,很重要的一點(diǎn):盡可能搞清楚問(wèn)題的前因后果!不要一下子就扎到服務(wù)器前面,你需要先搞明白對(duì)這臺(tái)服務(wù)器有多少已知的情況,還有故障的具體情況。不然你很可能就是在無(wú)的放矢。 必須搞清楚的問(wèn)題有:
另外也可以進(jìn)一步從應(yīng)用層、數(shù)據(jù)庫(kù)層、網(wǎng)絡(luò)層進(jìn)行檢查: 應(yīng)用層:
數(shù)據(jù)庫(kù):
網(wǎng)絡(luò):
盡可能地獲取到更多的已知有效信息,匯總信息并從多條排查線去進(jìn)行分析,這里推薦思路有:
這一步原則很簡(jiǎn)單:找出系統(tǒng)正在執(zhí)行“什么”,詢問(wèn)系統(tǒng)“為什么”執(zhí)行這些操作,以及系統(tǒng)的資源都被用在了“哪里”可以幫助你了解系統(tǒng)為什么出錯(cuò)。 四、擴(kuò)大你的信息量主動(dòng)擴(kuò)大信息的接收面,比如問(wèn)詢一下開(kāi)發(fā)或其它相關(guān)同學(xué),今天有沒(méi)有做線上改動(dòng),網(wǎng)絡(luò)組有無(wú)重大調(diào)整。從中獲取到有價(jià)值的信息點(diǎn),對(duì)于排查問(wèn)題至關(guān)重要。查看監(jiān)控,細(xì)看某個(gè)監(jiān)控項(xiàng)的變化,追蹤日志和調(diào)試信息都是擴(kuò)大信息量的手段。 拓展知識(shí)面,閑暇時(shí)間多些了解相關(guān)聯(lián)系統(tǒng),比如架構(gòu),部署,邏輯等。一旦故障發(fā)生,討論中也可提供你解決辦法的思路,舉一反三,推進(jìn)問(wèn)題的排查與解決。 收集問(wèn)題及環(huán)境信息,需要收集的信息可能有:
五、分析證詞,甄別對(duì)錯(cuò)如果是外部提出的問(wèn)題,比如業(yè)務(wù)投訴,用戶反饋等信息,有時(shí)候是可信的,有時(shí)候人卻是不可信的,舉個(gè)例子之前有開(kāi)發(fā)反饋效果有問(wèn)題,有些廣告位bias異常,有些正常,讓我們幫查查系統(tǒng)的問(wèn)題,但是最后是代碼調(diào)用一處動(dòng)態(tài)配置造成的。有些時(shí)候反饋的信息,是經(jīng)過(guò)描述者過(guò)濾加工過(guò)的信息,他的排查和分析有可能把你帶偏了,在收集信息同時(shí)需要以審視、懷疑的態(tài)度,分析每個(gè)人的證詞。 六、看清問(wèn)題本質(zhì)“當(dāng)你聽(tīng)到蹄子聲響時(shí),應(yīng)該先想到馬,而不是斑馬”,看到一件現(xiàn)象或一件事情,要看實(shí)質(zhì)而不只是表面的東西,聽(tīng)到馬蹄聲時(shí)候猜是什么馬,是什么人的馬,是來(lái)干什么的而不是猜它是斑馬還是白馬還是黑馬。排查問(wèn)題也一樣切忌先入為主,有時(shí)候你覺(jué)得極其簡(jiǎn)單,看似非常不可能發(fā)生的事情,可能就是原因,不要輕易的排除掉某項(xiàng)原因。例比:之前遇到有個(gè)mysql連接異常的問(wèn)題,查了很久,做了很多調(diào)優(yōu)都沒(méi)有解決,最后發(fā)現(xiàn)是網(wǎng)卡跑滿了。 七、確定方向,開(kāi)展定位排查步驟,可以先“從大到小”,先看比如運(yùn)營(yíng)商網(wǎng)絡(luò),機(jī)房狀態(tài)等比較宏觀的地方是否有問(wèn)題,逐一排除,逐步縮小問(wèn)題范圍。再“從上到下”,先從現(xiàn)象發(fā)生的頂端調(diào)用鏈逐一排查,逐步向下深入。 但也并不是所有問(wèn)題都從大到小從上到下,宏觀問(wèn)題只有達(dá)到一定量級(jí)才會(huì)引發(fā)”質(zhì)變”,從而引起的注意,在通往質(zhì)變過(guò)程中,你的業(yè)務(wù)可能已經(jīng)收到某中影響而表現(xiàn)的很明確,此時(shí)需要微觀分析,然后再逐漸到宏觀來(lái)診斷。 八、卷宗記錄,破案歸檔問(wèn)題排查解決后,養(yǎng)成事后總結(jié)的習(xí)慣。好記性不如爛筆頭,然而在一片混亂問(wèn)題分析當(dāng)中,心平氣和地記錄下問(wèn)題與判斷確實(shí)有點(diǎn)不切實(shí)際。但即使如此,我們?nèi)匀豢梢栽谑虑榻Y(jié)束后為保留一份分析資料,總結(jié)并記錄處理過(guò)程中的執(zhí)行步驟以及解決途徑,則能幫助自己和團(tuán)隊(duì)積累寶貴的處理經(jīng)驗(yàn)。
4. 長(zhǎng)期改進(jìn)建議吃一塹長(zhǎng)一智出了問(wèn)題并不可怕,怕的是我們從問(wèn)題中學(xué)不到什么,怕的是類(lèi)似的問(wèn)題重現(xiàn),提高問(wèn)題定位的效率,有哪些值得去做,比如: 1、建立長(zhǎng)效錯(cuò)誤碼機(jī)制,使用具統(tǒng)計(jì)、可視意義的數(shù)字來(lái)簡(jiǎn)短描述錯(cuò)誤含義和范疇,正所謂濃縮就是精華,這一點(diǎn)在錯(cuò)誤碼屢試不爽。 2、正常程序中打錯(cuò)誤日志主要是為了更好地排查問(wèn)題和解決問(wèn)題,提供重要線索和指導(dǎo)。但是在實(shí)際中打的錯(cuò)誤日志內(nèi)容和格式變化多樣,錯(cuò)誤提示上可能殘缺不全、沒(méi)有相關(guān)背景、不明其義,使得排查解決問(wèn)題成為非常不方便或者耗時(shí)的操作。而實(shí)際上只要開(kāi)發(fā)稍加用心,也需就會(huì)減少排查問(wèn)題的很多無(wú)用功。如何編寫(xiě)有效的錯(cuò)誤日志,建立日志標(biāo)準(zhǔn),也是非常有利于問(wèn)題分析的。 3、定位問(wèn)題避免二次損害,當(dāng)某個(gè)看似難以捉摸的難題出現(xiàn)時(shí),本能可能是重啟,盡快讓系統(tǒng)恢復(fù)正常。雖然這樣的方式經(jīng)常能夠解決問(wèn)題而且起效神速,但同時(shí)也很可能把情況推向令人難以置信的惡化深淵。問(wèn)題排查手段包括重新啟動(dòng)不穩(wěn)定系統(tǒng)、嘗試自動(dòng)記錄數(shù)據(jù)庫(kù)、文件系統(tǒng)修復(fù)等等,這些方式往往確實(shí)能搞定難題并讓系統(tǒng)重回生產(chǎn)軌道,但同時(shí)也沒(méi)準(zhǔn)導(dǎo)致數(shù)據(jù)恢復(fù)努力付之東流,毀掉確定問(wèn)題根本原因的機(jī)會(huì)甚至大大延長(zhǎng)關(guān)鍵性系統(tǒng)的停機(jī)時(shí)間。保留現(xiàn)場(chǎng)也非常重要,跟破案現(xiàn)場(chǎng)要要求現(xiàn)場(chǎng)勘察、樣本采集、排查、鎖定如出一轍,對(duì)于難以重現(xiàn)問(wèn)題,盡量創(chuàng)造條件保留了可以用于故障重現(xiàn)的數(shù)據(jù)或現(xiàn)場(chǎng)。線上環(huán)境復(fù)雜多變,雖然這一點(diǎn)并不能馬上解決問(wèn)題起到直接作用,但堅(jiān)持這種處理思路,為開(kāi)發(fā)和測(cè)試創(chuàng)造條件,降低因難以重現(xiàn)的疑難故障的掛起率,最終有助于業(yè)務(wù)的長(zhǎng)期穩(wěn)定。 4、建立集中的數(shù)據(jù)可視平臺(tái),不至于遇到問(wèn)題才開(kāi)始著手分析,若是對(duì)業(yè)務(wù)沒(méi)有足夠的了解又沒(méi)有數(shù)據(jù)依賴,就很可能在解決問(wèn)題時(shí)雪上加霜。 5、建立沙箱影子系統(tǒng),模擬復(fù)雜多變的現(xiàn)網(wǎng)環(huán)境,規(guī)避線上影響,重現(xiàn)或壓測(cè)問(wèn)題,如tcpcopy、dubbocopy等。 6、搭建開(kāi)源的日志可視方案,協(xié)助我們?nèi)ソ鉀Q最后”一公里”的問(wèn)題,常見(jiàn)如ELK、Log.io等。 7、善其事必先利其器,常見(jiàn)系統(tǒng)排查工具perf、iptraf、netperf、tcpdump、gdb、pstack、jstack、strace,top、iotop、tsar等。 8、在升級(jí)版本或者替換或修改文件時(shí),一定要做好備份,要保證隨時(shí)可以還原。 9、程序在使用多線程時(shí),盡可能的減少多線程競(jìng)爭(zhēng)鎖,可以將數(shù)據(jù)分段,各個(gè)線程分別讀取。 10、盡量不要在線程中做大量耗時(shí)的網(wǎng)絡(luò)操作,如查詢數(shù)據(jù)庫(kù)(可以的話在一開(kāi)始就將數(shù)據(jù)從從 DB 中查出準(zhǔn)備好)。 11、建議對(duì)線程取一個(gè)有意義的名稱,這樣對(duì)于在排查問(wèn)題時(shí)很有必要,如當(dāng)拿到程序線程堆棧信息時(shí),可直接根據(jù)線程名在日志中找到相關(guān)的堆棧。 12、生產(chǎn)環(huán)境進(jìn)行問(wèn)題排查時(shí)一定要保證不要影響正常的業(yè)務(wù)執(zhí)行。 先寫(xiě)這么多吧~ |
|