一招教你成為大內密探:診斷優化找出消耗CPU效能的內鬼

TestingGDR發表於2018-11-12

每次提起效能測試,都是開始於指令碼、壓力,然後各種監控,最後的最後就是分析。每次到了最後一個環境,所有大牛都說是一個很複雜的過程一兩句話說不清楚。讓人陷入了無盡的遐想~~~~~。

今天,測試就告訴你如何找到Java消耗CPU的程式是怎麼被找到的。

傳統的手段

當遇見CPU效能飆升到接近100的時候,首先需要進入對應的伺服器,然後通過如下一連串的動作找到最耗資源的罪魁禍首。

top發現最好是的程式

在shell介面中,輸入top,找到最消耗CPU的那個Java程式。記錄下PID號碼。

然後通過:

top -H -p pid

命令檢視對應PID程式下的執行緒,找到最耗資源的執行緒的PID。將其通過shell轉成十六進位制:

printf ”%x\n“ pid
%x,表示十六進位制,\n是換行

應用jstack針對上面耗時的執行緒進行分析

jstack PID(十六進位制)1> xxx.tmp

然後開啟xxx.tmp檔案,搜尋PID(十六進位制)號碼,下面的堆疊就是這個執行緒打出來的。排查問題就可以從這些堆疊資訊開整找到問題。

一個一勞永逸的工具

show-busy-java-threads用於快速排查Java的CPU效能問題(top us值過高),自動查出執行的Java程式中消耗CPU多的執行緒,並列印出其執行緒棧,從而確定導致效能問題的方法呼叫。

GitHub地址:https://github.com/oldratlee/useful-scripts

在伺服器端,克隆專案: git clone git://github.com/oldratlee/useful-scripts.git

cd useful-scripts

然後就可以看到了show-busy-jaa-threads工具了。其中,該Github倉庫有一個release釋出分支,裡面包含的都是功能穩定的指令碼,建議使用的時候切換到該分支。方法如下:

# 使用Release分支的內容
git checkout release
# 更新指令碼
git pull

進入userful-scripts目錄後,輸入 ./show-busy-java-threads就可以使用這個工具進行上述消耗CPU的優化分析了。其他show-busy-java-threads工具的用法如下:

show-busy-java-threads

# 從所有執行的Java程式中找出最消耗CPU的執行緒(預設5個),列印出其執行緒棧



# 預設會自動從所有的Java程式中找出最消耗CPU的執行緒,這樣用更方便

# 當然你可以手動指定要分析的Java程式Id,以保證只會顯示出那個你關心的那個Java程式的資訊

show-busy-java-threads -p <指定的Java程式Id>



show-busy-java-threads -c <要顯示的執行緒棧數>



show-busy-java-threads <重複執行的間隔秒數> [<重複執行的次數>]

# 多次執行;這2個引數的使用方式類似vmstat命令



show-busy-java-threads -a <執行輸出的記錄到的檔案>

# 記錄到檔案以方便回溯檢視



show-duplicate-java-classes -S <儲存jstack輸出檔案的目錄>

# 指定jstack輸出檔案的儲存目錄,方便記錄以後續分析



##############################

# 注意:

##############################

# 如果Java程式的使用者 與 執行指令碼的當前使用者 不同,則jstack不了這個Java程式

# 為了能切換到Java程式的使用者,需要加sudo來執行,即可以解決:

sudo show-busy-java-threads



show-busy-java-threads -s <指定jstack命令的全路徑>

# 對於sudo方式的執行,JAVA_HOME環境變數不能傳遞給root,

# 而root使用者往往沒有配置JAVA_HOME且不方便配置,

# 顯式指定jstack命令的路徑就反而顯得更方便了



# -m選項:執行jstack命令時加上-m選項,顯示上Native的棧幀,一般應用排查不需要使用

show-busy-java-threads -m

# -F選項:執行jstack命令時加上 -F 選項(如果直接jstack無響應時,用於強制jstack),一般情況不需要使用

show-busy-java-threads -F

# -l選項:執行jstack命令時加上 -l 選項,顯示上更多相關鎖的資訊,一般情況不需要使用

# 注意:和 -m -F 選項一起使用時,可能會大大增加jstack操作的耗時

show-busy-java-threads -l



# 幫助資訊

$ show-busy-java-threads -h

Usage: show-busy-java-threads [OPTION]... [delay [count]]

Find out the highest cpu consumed threads of java, and print the stack of these threads.



Example:

 show-busy-java-threads       # show busy java threads info

 show-busy-java-threads 1     # update every 1 second, (stop by eg: CTRL+C)

 show-busy-java-threads 3 10  # update every 3 seconds, update 10 times



Output control:

 -p, --pid <java pid>      find out the highest cpu consumed threads from the specified java process,

                           default from all java process.

 -c, --count <num>         set the thread count to show, default is 5.

 -a, --append-file <file>  specifies the file to append output as log.

 -S, --store-dir <dir>     specifies the directory for storing intermediate files, and keep files.

                           default store intermediate files at tmp dir, and auto remove after run.

                           use this option to keep files so as to review jstack/top/ps output later.

 delay                     the delay between updates in seconds.

 count                     the number of updates.

                           delay/count arguments imitates the style of vmstat command.



jstack control:

 -s, --jstack-path <path>  specifies the path of jstack command.

 -F, --force               set jstack to force a thread dump.

                           use when jstack <pid> does not respond (process is hung).

 -m, --mix-native-frames   set jstack to print both java and native frames (mixed mode).

 -l, --lock-info           set jstack with long listing. Prints additional information about locks.



cpu usage calculation control:

 -d, --top-delay           specifies the delay between top samples, default is 0.5 (second).

                           get thread cpu percentage during this delay interval.

                           more info see top -d option. eg: -d 1 (1 second).

 -P, --use-ps              use ps command to find busy thread(cpu usage) instead of top command,

                           default use top command, because cpu usage of ps command is expressed as

                           the percentage of time spent running during the entire lifetime of a process,

                           this is not ideal.



Miscellaneous:

 -h, --help                display this help and exit.

其實優化是效能測試的根本目標,找到問題後分析問題才是關鍵,通過各種手段找到更詳細的問題,找到更多的資料和RD一起分析。

結語:

最後跟大家推薦一個學習資料分享群:175317069,裡面大牛已經為我們整理好了許多的學習資料,有自動化,介面,效能等等的學習資料!

人生是一個逆水行舟的過程,不進則退,我們們一起加油吧!

相關文章