一次應(yīng)用啟動卡死問題排查記錄

“卡死”醇王,說的比較口語化,換個視角就有思路了:卡死就是線程阻塞了搁吓。

說一下背景原茅,項目都是 Java 應(yīng)用,容器是 tomcat堕仔,應(yīng)用發(fā)布就是 tomcat shutdown擂橘,然后 tomcat start,一般看啟動日志 catalina.out 能看到啟動時 spring ApplicationContext 啟動過程中的各種日志摩骨,中間件的加載也會輸出日志通贞。所以啟動卡死,看到的現(xiàn)象就是:打印了幾行日志恼五,就不往下繼續(xù)打印了昌罩,應(yīng)用一直處于不可用狀態(tài),直到發(fā)布超時灾馒。

從線程角度考慮茎用,此時就是線程阻塞住了,就需要知道各個線程是在做什么睬罗,找出可疑的線程轨功,順藤摸瓜,看它在干什么傅物。

一個實例

一直卡住夯辖,馬上現(xiàn)場定位, 執(zhí)行ps -ef | grep java 找出 tomcat 進(jìn)程的 pid董饰,然后執(zhí)行 jstack [pid]蒿褂,因為 tomcat 是應(yīng)用程序以 nobody 的身份啟動的圆米,所以提示權(quán)限不足,聯(lián)系運(yùn)維開通權(quán)限之后以 root 身份執(zhí)行即可啄栓。

tomcat 發(fā)布啟動的時候卡住娄帖,那就是主線程阻塞了,直接定位到以下線程堆棧:

"main" prio=10 tid=0x00007f99e0012800 nid=0x5246 waiting on condition [0x00007f99e74c5000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000e5a16058> (a java.util.concurrent.CountDownLatch$Sync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:994)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1303)
        at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:236)
        at com.xyz.client.http.domain.PollFuture.get(PollFuture.java:54)
        at com.xyz.client.http.PollWorker.get(PollWorker.java:107)
        - locked <0x00000000e2901da8> (a com.xyz.client.http.PollWorker)
        at com.xyz.client.http.ProjectManager.load(ProjectManager.java:200)

可以看到線程此刻處于 waiting 狀態(tài)昙楚,在等待什么呢近速?waiting on condition [0x00007f99e74c5000] 條件等待,繼續(xù)看堆棧堪旧,跟 CountDownLatch 有關(guān)削葱,繼續(xù)往棧下層看,com.xyz.client.http.domain.PollFuture.get 就是內(nèi)部中間件的代碼了淳梦,證明在 get 的時候阻塞在了 CountDownLatch.await()方法上了析砸。

到這一步,基本可以拿著堆棧找中間件相關(guān)的同事定位了爆袍,一般還可以找到此時中間件相關(guān)的一些日志首繁,注意 ERROR級別的日志,幫助他們更快找到問題陨囊。

作為思考弦疮,想想為什么阻塞在 await 了?了解 CountDownLatch 的原理就可以想到蜘醋,一定是某個地方?jīng)]有執(zhí)行 latch.countDown() 操作胁塞,或者執(zhí)行的次數(shù)不夠√煤看 PollFuture 相關(guān)的代碼闲先,有如下聲明,this.latch = new CountDownLatch(1); 這就更好定位了无蜂,證明 countdown 一次沒執(zhí)行成功伺糠,搜索執(zhí)行 countdown 操作的地方,只有一處斥季,如下:

    public void setResult(Object result) {
        this.result = result;
            if(result == null) {
                // no changes
                return;
            }
           // do something
        latch.countDown();
    }

于是可以知道训桶,這里 result == null 成立,往上層繼續(xù)排查就是了酣倾。

最終定位下來舵揭,某個極端條件下,setResult() 前一步的請求出錯躁锡,返回 error 信息午绳,于是處理出來的 result 為空。

另一個例子

上面的例子是啟動完全阻塞映之,永遠(yuǎn)不會繼續(xù)拦焚。這個例子的現(xiàn)象是 tomcat 啟動超時蜡坊,表現(xiàn)就是斷斷續(xù)續(xù)輸出日志,部分機(jī)器啟動能成功赎败,部分不成功秕衙,其實也不是完全不會啟動,只是超過了timeout = 50000ms的啟動超時時長僵刮,發(fā)布系統(tǒng)就提示啟動失敗据忘。

一樣的思路,重新發(fā)布超時的機(jī)器搞糕,然后登錄上去勇吊,jstack [pid] 輸出若干線程信息,但是只看到有些線程 waiting 窍仰,多執(zhí)行幾次命令萧福,又發(fā)現(xiàn)有時會繼續(xù)執(zhí)行。

聯(lián)系架構(gòu)的同事辈赋,也是一樣的操作,執(zhí)行若干次命令之后膏燕,觀察幾次輸出的差異钥屈,看到有個線程會 sleep,這個線程此時的動作是:去遠(yuǎn)程拿一批服務(wù)注冊項信息坝辫。順著堆棧信息進(jìn)一步定位發(fā)現(xiàn)篷就,這個是 RPC 框架調(diào)用內(nèi)部另一個組件的接口拿注冊項信息,該接口的處理是:獲取超時就 sleep 3s近忙,然后再獲取竭业,重試 n 次。多番定位之后及舍,升級組件解決問題未辆。

由此可以看出,定位線程阻塞問題锯玛,一次輸出甚至多次輸出可能還不夠咐柜,對引入的組件代碼不熟悉,可能也無法確認(rèn)問題攘残。熟悉代碼的人大致知道哪些地方拙友,哪些后臺線程可能阻塞。還有賴于平時多積累歼郭,遇到問題多請教遗契。

總結(jié)

記得兩年前,同事遇到過一次定時任務(wù)發(fā)布的時候啟動卡死的問題病曾,當(dāng)時直覺可能跟線程死鎖有關(guān)牍蜂,不過我們都沒有想到怎么入手排查漾根。當(dāng)時所有排查問題的思路都局限于“看代碼”、設(shè)置斷點捷兰、加日志立叛,差別無非是,測試環(huán)境可以調(diào)試贡茅,就靠斷點秘蛇,生產(chǎn)環(huán)境要求嚴(yán)格、不能影響服務(wù)顶考,所以只能靠日志和代碼赁还,總的來說,都局限在自己維護(hù)的業(yè)務(wù)代碼中驹沿,進(jìn)了斷點艘策,什么都好說,這類不知道怎么加斷點的問題渊季,就束手無策朋蔫。

從線程阻塞類問題可以認(rèn)識到,有時候要從整個運(yùn)行時體系去考慮却汉,甚至要從部署結(jié)構(gòu)考慮驯妄,轉(zhuǎn)換視角能發(fā)現(xiàn)更多問題,也會有更多方法合砂。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末青扔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子翩伪,更是在濱河造成了極大的恐慌微猖,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缘屹,死亡現(xiàn)場離奇詭異凛剥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)轻姿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進(jìn)店門当悔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人踢代,你說我怎么就攤上這事盲憎。” “怎么了胳挎?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵饼疙,是天一觀的道長。 經(jīng)常有香客問我,道長窑眯,這世上最難降的妖魔是什么屏积? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮磅甩,結(jié)果婚禮上炊林,老公的妹妹穿的比我還像新娘。我一直安慰自己卷要,他們只是感情好渣聚,可當(dāng)我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著僧叉,像睡著了一般奕枝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓶堕,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天隘道,我揣著相機(jī)與錄音,去河邊找鬼郎笆。 笑死谭梗,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宛蚓。 我是一名探鬼主播默辨,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼苍息!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起壹置,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤竞思,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后钞护,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盖喷,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年难咕,在試婚紗的時候發(fā)現(xiàn)自己被綠了课梳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡余佃,死狀恐怖暮刃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情爆土,我是刑警寧澤椭懊,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站步势,受9級特大地震影響氧猬,放射性物質(zhì)發(fā)生泄漏背犯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一盅抚、第九天 我趴在偏房一處隱蔽的房頂上張望漠魏。 院中可真熱鬧,春花似錦妄均、人聲如沸柱锹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奕纫。三九已至,卻和暖如春烫沙,著一層夾襖步出監(jiān)牢的瞬間匹层,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工锌蓄, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留升筏,地道東北人。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓瘸爽,卻偏偏與公主長得像您访,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子剪决,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 從三月份找實習(xí)到現(xiàn)在灵汪,面了一些公司,掛了不少柑潦,但最終還是拿到小米享言、百度、阿里渗鬼、京東览露、新浪、CVTE譬胎、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,278評論 11 349
  • 一差牛、多線程 說明下線程的狀態(tài) java中的線程一共有 5 種狀態(tài)。 NEW:這種情況指的是堰乔,通過 New 關(guān)鍵字創(chuàng)...
    Java旅行者閱讀 4,687評論 0 44
  • 愛上他這件事只有自己知道偏化,苦澀也要自己承受。不知道怎么向別人描述這段單戀镐侯,即使是最了解我的人夹孔。我愛上有婚約的人,愛...
    最佳損友王小魚兒閱讀 311評論 0 0
  • 文/小暮 我們都渴望著外面精彩的世界,因為精彩的生活里總有很多驚喜和意外搭伤,誰也不想每天重復(fù)單調(diào)無聊的生活只怎。 可有時...
    歲月小暮閱讀 583評論 0 1
  • 參考上課所講的內(nèi)容電商案例,結(jié)合自主尋找的和自己經(jīng)營產(chǎn)品相關(guān)的內(nèi)容怜俐,組織一篇上題中的產(chǎn)品的推廣文章身堡,字?jǐn)?shù)不限,但需...
    cb6028db333e閱讀 158評論 0 0