tomcat佔用cpu過高解決方法

問題描述

在工作中經常遇到tomcat佔用cpu居高不下,top顯示結果超過200%,請求無法響應,針對這種情況有以下處理辦法進行排查。請求無法響應。


問題排查

1、獲取進程信息

通過jdk提供的jps命令可以快速查出jvm進程

jps pid

2、查看jstack信息

jstack pid


3、將十進制pid轉換爲16進制

將十進制轉換成16進制
# printf "%x\n" 19713-->將第2步查到佔用較高CPU的線程號轉換爲16進制,以便於jstack查看
4d01

#jstack pid | grep 0x4d01--> 0x4d01爲第3步19713轉換爲16進制後的數字,因爲jstack顯示的線程號是以16進製表示的!

將16進制轉換成十進制
# printf "%d\n" 0x4d19

jstack的作用是顯示正在運行的所有java線程情況,jstack pid | grep 0x4d01的意思只顯示某個java線程的運行信息。通過這種方法,可以將此線程正在運行的方法顯示出來,將此方法交給開發即可。(也可能jstack pid | grep 0x4d01什麼都沒有出來的


4、打印線程的堆棧信息

jstack pid | grep tid -A 30

此處不一一列表各tid的堆棧信息了,在其中一個的tid堆棧信息中找到了問題的原因


5、進一步排查,分析每個線程的cpu佔用量

簡單點兒的方法則是,查出進程id後,通過如下命令查看該進程中每個線程的資源使用情況

top -H -p pid   -H用於顯示某個進程的所有線程

從這裏獲取pid(線程id),轉換爲16進制,然後去stack信息中查找對象的線程信息。

通過上述方法,查出tomcat進程對應的線程cpu佔用率累積之和約80%,遠小於top給出的200%+

說明並不存在長期佔用cpu的線程,應該是屬於有許多短暫性的cpu密集計算。進而懷疑是不是jvm內存不足,頻繁gc導致。

jstat -gc pid

發現jvm內存使用並未出現異常,gc次數明顯暴漲

查完內存,由於本身是一個網絡程序,進一步排查網絡連接。


6、問題定位

查詢tomcat對應端口的tcp鏈接,查看是否存在大量EASTABLISH的鏈接,或還有部分其它狀態的連接。

netstat -anlp | grep port


netstat狀態說明:

LISTEN:偵聽來自遠方的TCP端口的連接請求
SYN-SENT:再發送連接請求後等待匹配的連接請求(如果有大量這樣的狀態包,檢查是否中招了)
SYN-RECEIVED:再收到和發送一個連接請求後等待對方對連接請求的確認(如有大量此狀態,估計被flood***了)
ESTABLISHED:代表一個打開的連接
FIN-WAIT-1:等待遠程TCP連接中斷請求,或先前的連接中斷請求的確認
FIN-WAIT-2:從遠程TCP等待連接中斷請求
CLOSE-WAIT:等待從本地用戶發來的連接中斷請求
CLOSING:等待遠程TCP對連接中斷的確認
LAST-ACK:等待原來的發向遠程TCP的連接中斷請求的確認(不是什麼好東西,此項出現,檢查是否被***)
TIME-WAIT:等待足夠的時間以確保遠程TCP接收到連接中斷請求的確認
CLOSED:沒有任何連接狀態


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章