排查思路
當(dāng)正在運(yùn)行的Java服務(wù)導(dǎo)致服務(wù)器的CPU突然飆高時(shí),我們該如何排查定位到哪個(gè)接口的哪行代碼導(dǎo)致CPU飆高的問題呢?我主要提供兩個(gè)方案:
- jstack
- arthas
準(zhǔn)備工作
代碼準(zhǔn)備
現(xiàn)在需要準(zhǔn)備一段可以讓服務(wù)器CPU飆高的代碼以及把代碼部署到服務(wù)環(huán)境。
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("top")
public void test() {
while (true) {
}
}
}
打包
使用maven打包或者Docker服務(wù)將代碼部署到服務(wù)器。
#整流程
mvn clean
mvn compile
mvn package
在IDEA中為:
簡單部署
java -jar demo1-0.0.1-SNAPSHOT.jar > demo.log &
jstack
jstack 是 JDK 提供的一個(gè)命令行工具,用于生成 Java 進(jìn)程的線程轉(zhuǎn)儲(chǔ)信息(也稱為線程快照)。它可以幫助診斷和調(diào)試 Java 應(yīng)用程序的線程相關(guān)問題,如死鎖、線程等待、線程占用CPU過高等。
jstack 命令可以在運(yùn)行中的 Java 進(jìn)程上執(zhí)行,它會(huì)輸出當(dāng)前 Java 進(jìn)程中所有線程的堆棧跟蹤信息。這些信息包括每個(gè)線程的方法調(diào)用棧、鎖信息、線程狀態(tài)等。
以下是 jstack 的一些常見用途和作用:
- 線程分析:jstack 生成的線程轉(zhuǎn)儲(chǔ)信息可以顯示 Java 進(jìn)程中所有線程的堆棧跟蹤信息。您可以查看每個(gè)線程的調(diào)用棧,了解線程執(zhí)行的代碼路徑和方法調(diào)用關(guān)系。
- 死鎖檢測:通過查看線程的鎖信息,jstack 可以幫助您發(fā)現(xiàn)是否存在死鎖情況。它會(huì)顯示每個(gè)線程當(dāng)前持有的鎖和等待的鎖,以及導(dǎo)致死鎖的鎖依賴關(guān)系。
- 線程等待:jstack 可以顯示線程的等待狀態(tài),幫助您確定是否存在線程等待某個(gè)資源的情況。這對于排查程序在運(yùn)行時(shí)出現(xiàn)的卡死或長時(shí)間無響應(yīng)問題非常有用。
- CPU 使用分析:通過查看線程的 CPU 使用情況,jstack 可以幫助您確定哪些線程消耗了大量的 CPU 資源,找出可能導(dǎo)致 CPU 占用過高的原因。
- 線程狀態(tài)監(jiān)控:jstack 提供了對線程狀態(tài)的監(jiān)控,您可以了解線程的狀態(tài),如運(yùn)行、阻塞、等待等,以便更好地理解應(yīng)用程序的運(yùn)行情況。
獲取CPU飆高的進(jìn)程PID
top命令用于監(jiān)視 Linux 系統(tǒng)的實(shí)時(shí)進(jìn)程和系統(tǒng)性能信息。那么我們可以通過top命令來實(shí)時(shí)定位到那個(gè)線程占用大量CPU資源。
輸入命令:
top
可以看到PID列中進(jìn)程id為8066的進(jìn)程CPU占用率達(dá)到了98.7%,那么我們接下來排查的就是這個(gè)進(jìn)程。
定位進(jìn)程中的問題線程
top -H -p PID
該命令的作用是在 top 工具中顯示指定進(jìn)程ID(PID)的線程級(jí)別信息。它將以線程級(jí)別的模式顯示指定進(jìn)程的各個(gè)線程的詳細(xì)信息。
具體解釋如下:
- -H 選項(xiàng)指示 top 以線程級(jí)別的模式顯示信息。
- -p pid 選項(xiàng)指定需要顯示信息的進(jìn)程ID(PID)。在這個(gè)例子中,PID 為 8066 的進(jìn)程的線程信息將被顯示。
將PID進(jìn)程號(hào)轉(zhuǎn)為16進(jìn)制
以上已定位具體線程pid導(dǎo)致CPU飆高,那么將指定pid轉(zhuǎn)換為16進(jìn)制,以便下一步定位具體線程問題使用。
將一個(gè)十進(jìn)制的進(jìn)程ID(PID)轉(zhuǎn)換為十六進(jìn)制格式的字符串,可以使用 printf 命令來實(shí)現(xiàn)。printf 命令可以根據(jù)指定的格式將數(shù)據(jù)進(jìn)行格式化輸出。
printf '0x%x\n' pid
定位指定線程問題
jstack pid | grep hexadecimal -A N
具體解釋如下:
- jstack pid 用于執(zhí)行 jstack 命令并生成線程轉(zhuǎn)儲(chǔ)信息。
- | 是管道符號(hào),將 jstack 命令的輸出傳遞給下一個(gè)命令。
- grep hexadecimal 表示使用 grep 命令來匹配包含 "hexadecimal" 的行。
- -A N 選項(xiàng)指定在匹配到的問題代碼行后顯示 N 行內(nèi)容。
那么可以很快定位到是TestController類第20行出現(xiàn)了問題。
那么我們看代碼:
arthas
Arthas 是一款線上監(jiān)控診斷產(chǎn)品,通過全局視角實(shí)時(shí)查看應(yīng)用 load、內(nèi)存、gc、線程的狀態(tài)信息,并能在不修改應(yīng)用代碼的情況下,對業(yè)務(wù)問題進(jìn)行診斷,包括查看方法調(diào)用的出入?yún)ⅰ惓?,監(jiān)測方法執(zhí)行耗時(shí),類加載信息等,大大提升線上問題排查效率。
下載
curl -O https://arthas.aliyun.com/arthas-boot.jar
運(yùn)行
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
運(yùn)行時(shí)arthas會(huì)提示用戶選擇哪個(gè)Jar服務(wù),那么我們選擇【1】,按1即可。
開始監(jiān)控。
排查占用最高的線程
thread -n 1
使用arthas可以更快定位問題代碼行。
更多使用技巧請參考官方文檔:文章來源:http://www.zghlxwxcb.cn/news/detail-688699.html
Arthas文章來源地址http://www.zghlxwxcb.cn/news/detail-688699.html
到了這里,關(guān)于服務(wù)器CPU飚高排查的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!