tomcat要運行依賴於JDK,tomcat服務器的CPU使用率過高,大多都是因為部署的web程序的問題。
一、現象描述
在一次線上環境,前台訪問頁面的速度越來越慢,從瀏覽器F12中看到發出的請求都是pengding的狀態。
二、排查過程
我這里tomcat部署在linux環境中。下面的排查過程均在linux下進行。
1、排查后台服務
查看tomcat的后台日志,發現日志正常打印,未發現異常信息;把要執行的SQL復制出來,放到mysql的客戶端執行,發現sql運行正常且查詢速度正常。
通過上面的排查發現要訪問的功能正常,排除是當前功能造成的原因。
2、排查服務器
1、找出耗CPU的進程
使用top命令查看特定用戶(user1)的內存、cpu及各進程的信息,
top -u user1
使用上面的命令,可以看到下面的信息,
從上面可以看到存在一個java的進程,由於我這里沒有其他的java相關的進程,這里可以判斷為tomcat的進程,這里可以看到PID為47787,通過%CPU、%MEM分別表示CPU、內存的使用率,由於我這里問題已經解決,所以看到CPU的使用率已經下來了,異常情況下可以是超過100%的數值。
這樣我們就可以找出使用CPU過高的進程。
還可以通過下面的命令來快速找到java進程,
jps
使用jps命令可以快速找到java進程的PID,如下圖
這里可以看出PID為47787為tomcat進程。還可以使用下面的命令,
ps -ef |grep tomcat
上面的命令打印出下方的信息,
回到正題,上面使用top命令找到了CPU過高的進程。
2、找出耗CPU的線程
在上一步中找到了耗CPU的進程,下面要找到耗CPU的線程。我們知道一個進程中可以有多個線程,進程是線程的集合。
使用下面的命令找到耗CPU的線程,
top -Hp 47787
上面的“47787”即上一步中找到進程id,意思就是找出該進程下的線程信息。如下圖,
從上圖中可以看到該進程下的線程信息,由於我這里已經正常了,所以未看到CPU過高的線程,上圖中的PID這里代表的是線程ID。假如47875這個線程的%CPU使用過高,
下面把該線程ID,轉化為16進制。
printf "%x\n" 47875
從上圖可以看出47875的16進制為“bb03”。
上面,通過進程ID,找到了耗CPU的線程ID,並且轉化為了16進制。
3、從JVM堆棧中查找線程信息
我們獲得了耗時較高的線程ID,下面通過JVM的堆棧信息找到線程信息,那么如何獲得JVM的堆棧信息那,使用下面的命令
jstack 47787 > ./jvm.log
上面的“47787”代表的是上面的進程ID,打印出47787進程的堆棧信息,保存在當前目錄的jvm.log文件中。
下面從jvm.log文件中找到上面的線程信息,
grep -rn bb03 ~/jvm.log -A 100
找到下面的信息,
從上面可以看到是一些線程信息,那要怎么去排查那,可以通過上圖紅框中的狀態為RUNNABLE的線程信息,即為正在運行的線程,從這里可以找到相關的信息,最終解決問題。
三、總結
CPU使用率過高,多數是因為線程無法終止或出現死循環等原因,需具體問題具體分析。