2023.07.20 20:01:38線上一個服務發生了CPU過高的告警,
看告警資訊當前的CPU使用率已經達到了82.65%,問題已經很嚴重,趕緊開始排查起來。來複盤下如何排查這類問題,
收到告警後,第一件事要做的就是找到CPU過高的程式的執行緒id(pid),可以使用jps或ps -ef |grep java兩個命令均可,
使用jps命令
jps
得到下面的結果
也就是程序ID是6。
再看使用ps的結果
使用ps命令
ps -ef |grep java
得到下面的結果
可以看到程序ID也是6。
當然除了上面兩個命令,還可以使用top,也可以很快找到CPU過高的服務程序ID。
我們已經知道了cpu過高的服務程序ID是6,但僅知道程序ID是無用的,需要進一步知道這個程序中哪些執行緒佔用CPU過高。
這裡使用的是top命令
top -Hp 6
得到的結果如下
可以看到執行緒1110 1125 1112 1121等佔用CPU過高,基本都在80%,基本可以斷定就是這些執行緒在佔用CPU。
找到佔用CPU過高的執行緒後,就要看下相應的堆疊資訊。
使用jstack命令,jstack命令可以列印出程序的堆疊,通過堆疊資訊可以分析到執行緒的執行情況,
jstack -l 6
可以看到很多類似這樣的資訊,這些資訊中有一個很重要的那就是nid=0x11,這個是代表的執行緒ID,聰明的你也一定知道這裡是16進位制,和剛才使用top -Hp命令看到的不一樣,那裡是10進位制的。
為了找到執行緒佔用cpu過高的堆疊,需要把執行緒ID做一次進位制轉換,既由10進位制轉換為16進位制,
例,1110--》0x456 1125--》0x465
以0x465為例,在堆疊中查詢相應的執行緒堆疊,
使用0x465查詢其對應的執行緒堆疊
可以看到執行緒0x465的執行緒狀態是RUNNABLE,而且看到了很多正則的呼叫,繼續往下看,找到了呼叫的程式碼,
最後分析是由於死迴圈引起的執行緒佔用CPU過高。
上面是我把檔案下載下來進行的查詢,那如何生成堆疊檔案,可以使用下面的命令
jstack -l 6 > dump.txt
生成後下載到本地即可。
如果線上環境無法下載,則只能通過命令進行查詢
jstack -l 6 | grep -A 10 0x465
這樣便可以看到相應的內容了。
有沒有覺得使用jstack命令匯出檔案後自己分析很麻煩,沒事有工具,可以使用fastthread。
其網址是:https://fastthread.io/
將jstack或者其他工具dump的堆疊檔案上傳到該網站同樣可以分析出結果。
將剛才的檔案上傳後,得到分析報告,由於是分析CPU過高,重點看cpu threads即可。
可以看到nativeId:1125即對應top -Hp出的執行緒ID,這裡fastThread已經進行了進位制轉換,無需手動操作了,很貼心。點選檢視完整的堆疊資訊即可分析出相應的問題。
一般程式CPU過高,大多數和死迴圈有關,分析此類問題的一般步驟是,
1、使用jps/ps -ef |grep java/top等命令找到程序ID,即pid;
2、使用top -Hp pid 找到程序中佔用CUP的執行緒ID;
3、使用jstack列印堆疊;
4、使用執行緒ID在堆疊中找到對應的執行緒堆疊;
5、分析執行緒堆疊,找到問題;
參考:
(7條訊息) jstack命令解析_fightingD&W的部落格-CSDN部落格
Linux命令之Grep——文字搜尋 - 閱讀清單 - 騰訊雲開發者社群-騰訊雲 (tencent.com)
推薦閱讀
花了半天時間,使用spring-boot實現動態資料來源,切換自如