快速定位線上CPU100%原因

引言

最近項目部門反應有個系統特別卡頓,很多頁面都打不開了,開發人員告訴我說最近沒有進行代碼升級,我登錄到對應的服務器上執行了top命令,發現cpu飆升到100%,對於這種問題我們應該快速的定位到問題,否則會影響線上系統的正常作業。

對於造成這種問題的可能原因,迅速的在頭腦中閃過四種情況:

  1、某個接口響應時間超長,並且可能被頻繁調用

  2、產生了過大的對象,造成頻繁FGC

  3、代碼出現死循環

  4、線程出現死鎖

 下面是小編的定位問題的步驟:

  1)top

   2)top  -Hp 2848

   3)printf "%x" 2925

   4)jstack 2848 | grep 0xb6d -C50 --color

第一、執行top命令,結果如下

我們根據top結果發現,有java進程CPU佔用超過100%,說明這個進程中的代碼出現問題了

第二、執行top  -Hp 2848 查看該pid詳情

從上面結果,我們基本可以排除產生大對象的情況,因爲如果有大對象產生,這個時候的結果應該是有多個進程CPU佔用都會超過80%,其中有多個進程在在進行GC,從而造成CPU飆升。

第三  執行 printf "%x" 2925 轉換爲 十六進制

第四 執行 jstack 2848 | grep 0xb6d -C50 --color 查看具體的信息,由於我們項目使用daemon用戶啓動,所以我執行的命令爲

/sbin/runuser -s /bin/bash daemon -c "jstack 2848 | grep 0xb6d -C50 --color"
 

上圖中紅色的nid就是我們查看的進行對應的詳細代碼信息,從上面我們就可以很快的定位到具體的代碼行,我們系統此處代碼是一個統計的方法,由於前端傳遞的時間跨度非常大,並且多個人在頻繁的刷新造成系統卡死。

注意:我們執行jstack的時候,執行用戶需要和進程啓動用戶一直,否則會提示下面錯誤

Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding

********************下面我們分析一下 代碼執行過程中產生 "超大對象" 出現的現象***************************************

1、top

2、 執行命令 top -Hp 23002

我們發現有很多的進程cpu佔用都查過了90%,這種情況很可能是多個進程在進行FGC,爲了驗證這種情況我們執行下面命令

3、jstat -gcutil 23002 2000 5

上面命令是 輸出該進程在jvm中的佔用情況  每2000毫秒執行一次 一共執行5次

從輸出信息可以看出,Eden區內存佔用100%,Old區內存佔用99.97%,Full GC的次數高達170次,並且頻繁Full GC,Full GC的持續時間也特別長,平均每次Full GC耗時5.93秒(1009.445/170)。根據這些信息,基本可以確定是程序代碼上出現了問題,可能存在不合理創建對象的地方 

4、將上面的對應的四個線程號十進制轉換爲 十六進制

5、執行命令 jstack 23002 |grep "0x59dd" -C50 --color 查看對應的線程信息

由上圖可見,cpu使用率高的線程都在GC task,JVM的GC線程一直在佔用大量CPU

6、也可以執行命令jstack -l 23002 >/data1/23002.statck 將對應的進程號的棧信息輸入到指定目錄

7、在23002.statck中就行過濾查詢 

 

7、過濾搜索一下 我們項目名稱,就可以看到具體的代碼位置

8、然後根據具體的代碼分析一下,出現 問題的具體原因

小結

線上出現cpu100%問題需要我們在最短的是時間內解決該問題,其中最重要的是我們能快速的定位到問題出現的具體代碼位置,然後我們才能在最短的時間內解決,對於一些不是很重要的統計功能,我們可以先暫停該功能,首先保證主要流程正常使用,待服務恢復正常以後,我們在 優化具體的代碼。

發佈了364 篇原創文章 · 獲贊 389 · 訪問量 141萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章