首先,先用放之四海而皆準的命令 top,確認一下是不是 Java 進程是罪魁禍首。Java 進程要不然就是個后臺任務,要不然就是個 jar 包,比如一個Spring Boot 服務。
剛接觸開發那會兒,別的命令都不會,一看到CPU飆升,上來就是一個 top,當top 命令執行完了,也就完了。就像一個舉重選手用盡了所有力氣,然后就只能呆坐在哪里了。
下面介紹兩種后續操作,讓我們在執行完 top以后,確定是 Java 進程搞的鬼的情況下,順利的找出出現問題的方法。
第一種,用系統工具和 JDK 自帶的 jstack 工具。第二種,用 Arthas 探測工具。
使用 jstack 工具
第一步,使用 top 找到占用 CPU 最高的 Java 進程
前面說了這一步,就是使用 Top 命令
使用 top命令發現占用 CPU 99.7% 的線程是 Java 進程,進程 PID 為 13731。
第二步,找到占用 CPU 最高的線程
上一步用 top命令找到了那個 Java 進程。那一個進程中有那么多線程,不可能所有線程都一直占著 CPU 不放,這一步要做的就是揪出這個罪魁禍首,當然有可能不止一個。
接下來,還是用 top命令,只不過加一個參數-Hp ,就是下面這樣
top-Hppid
H參數表示要顯示線程級別的信息,p則表示指定的pid,也就是進程id。代入前面得到的那個Java進程,完整的命令是這樣的
top-Hp13731
執行之后,這個Java進程中占用線程占用 CPU 的情況就列出來了。
可以看到占用 CPU 最高的那個線程 PID 為 13756。
第三步,保存線程堆棧信息
這就要用到 JDK 默認提供的一個工具了,叫做 jstack。當你安裝了 JDK 之后,在 bin目錄下會有一大堆內置的工具,java也是其中之一,還有另外我們可能比較熟悉的 javac
jstack 用于生成 Java 進程的線程快照(thread dump)。線程快照是一個關于 Java 進程中所有線程當前狀態的快照,包括每個線程的堆棧信息。通過分析線程快照,可以了解 Java 進程中各個線程的運行狀態、鎖信息等。
我們用jstack的目的就是將那個占用 CPU 最高的線程的堆棧信息搞下來,然后進一步分析。使用命令 jstack pid > out.log將某個進程的堆棧信息輸出到 out.log文件中。
當前 Java 程序的所有線程信息都可以通過 jstack命令查看,我們用jstack命令將第一步找到的 Java 進程的線程棧保存下來。
jstack13731>thread_stack.log
第四步,在線程棧中查找最貴禍首的線程
第二步已經找到了這個罪魁禍首的線程 PID 是 13756。
然后我們將 13756轉換為 16 進制的,可以用在線進制轉換的網站直接轉換,比如 https://tool.oschina.net/hexconvert 這個,轉換結果為 0x35bc。
最后,我們在線程棧中,也就是上一步保存的那個 thread_stack.log 文件,在里面查找這個16進制的線程 id (0x35bc)。
然后,我么能看到了我們需要的線程名稱、線程狀態,哪個方法的哪一行代碼消耗了最多的 CPU 都很清楚了。
第二種,Arthas
Arthas 是阿里開源的一款線上監控診斷產品,通過全局視角實時查看應用 load、內存、gc、線程的狀態信息,并能在不修改應用代碼的情況下,對業務問題進行診斷,包括查看方法調用的出入參、異常,監測方法執行耗時,類加載信息等,大大提升線上問題排查效率。
用 Arthas 查找占用 CPU 最高的方法只是一個開胃小菜,除此之外,它最大的用途是在不改代碼、不重啟服務的情況下對程序進行動態監控。如果你碰到了線上詭異問題,一定要用 Arthas 嘗試找一找問題,開闊一下眼界。
好了,更多的功能到官網 https://arthas.aliyun.com/ 了解吧,接下來就將一下如何用 Arthas 達到前面用 jstack 同樣的目的。
安裝 Arthas
當然了,要使用 Arthas,你就必須先把它安裝到你的目標服務器上,也就是那個出問題的Java服務所在的服務器。
下載 jar 包
curl-Ohttps://arthas.aliyun.com/arthas-boot.jar
啟動 Arthas 服務
java-jararthas-boot.jar
啟動之后,會列出當前這臺服務器上的所有 Java 進程,然后你選擇你要排查的那個服務即可。
然后出現 arthas@之后表示已經啟動,并成功 attach 到目標進程上 。
然后可以輸入命令 dashboard看一下實時面板,默認 5 秒刷新一次,在這個面板上能夠看到線程、內存堆棧、GC和Runtime的基本信息。如果你用過 VisualVM 的話,就和那個基本一樣。
好了,開始用 Arthas 找到導致 CPU 負載過高的問題吧。
找到占用CPU最高的進程
第一步,其實還是用 top命令找到占用 CPU 最高的進程,也就是 Arthas 啟動時選擇 attach 的那個 Java 進程。
然后 java -jar arthas-boot.jar啟動Arthas,并attach 。
找到占用 CPU 最高的線程
執行 thread命令,這個命令會顯示所有線程的信息,并且把CPU使用率高的線程排在前面。
這樣,一眼就看出來了,第一個線程的 CPU 使用率高達 99% 了,就是它。
查看堆棧信息
使用 thread ID 獲取堆棧信息,其實就是 jstack pid相同的作用。通過前一步看到這個線程的 ID 是18,然后執行 thread 18
然后直接就看出來了出現問題的位置,TestController.java文件的 high方法的第23行。然后進代碼看
com.moonkite.wallpapermanage.controller.TestController.high(TestController.java:23)
這個方法是我故意寫的死循環,真實情況當然沒有這么明顯,還需要針對具體代碼認真分析。
總結
高 CPU 占用率這個問題是一種很常見也很典型的線上問題,排查方式只要按上述順序記下來就基本上沒什么問題。
其實還是推薦使用 Arthas,除了它確實功能非常多之外,還有就是在線上場景下,使用 jstack有時會碰到問題,如果這個線程已經忙的一點轉圜的余地都沒有了,jstack命令可能會執行失敗。
審核編輯:劉清
-
cpu
+關注
關注
68文章
10902瀏覽量
213016 -
JAVA
+關注
關注
19文章
2974瀏覽量
105147
原文標題:面試官:CPU 100% 問題怎么排查?
文章出處:【微信號:小林coding,微信公眾號:小林coding】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論