線上環境CPU使用率飆升,如何排查
1.CPU飆升的常見原因
1. 代碼層面問題
- 死循環:錯誤的循環條件導致無限循環
- 遞歸過深:沒有正確的終止條件
- 算法效率低:O(n2)或更高時間復雜度的算法處理大數據集
- 頻繁GC:內存泄漏導致頻繁垃圾回收
2. 并發問題
- 線程阻塞:過多的線程等待資源(鎖、數據庫連接等)
- 線程爆炸:創建過多線程,上下文切換開銷大
- 鎖競爭:激烈的鎖競爭導致線程頻繁掛起和喚醒
3. 外部依賴問題
- 數據庫:慢查詢、全表掃描、缺少索引
- 外部API:響應變慢或阻塞
- 網絡IO:網絡延遲或帶寬瓶頸
4. 資源問題
- 內存不足:頻繁的GC操作消耗CPU
- 磁盤IO:大量的磁盤讀寫操作
5. 配置問題
- JVM參數:不合理的堆大小、GC參數等
- 線程池配置:不合理的線程池大小
2.模擬線上環境cpu飆升
條件準備
主要是用于演示,當線上環境出現cpu飆升時,怎么去排查問題,因此此處就使用死循環去構造該場景
如上所示,項目結構也是及其的簡單,定義一個接口,用于訪問,觸發死循環的執行,用于構造cpu飆升的場景
代碼打包部署
將項目打包為jar包,在虛擬機上部署運行
# 參考命令
java -jar high-cpu-1.0-SNAPSHOT.jar
# 后臺運行
nohup java -jar high-cpu-1.0-SNAPSHOT.jar &
運行之后檢查下是否成功
然后對接口發起請求http://ip:10003/high/cpu,執行while循環
3 排查步驟
獲取所有進程執行信息
首先使用top命令,查看線程的占用情況
[root@mycentos local]# top
可以確認PID為93992的進程,占用cpu最高
查看指定進程的各線程的執行信息
使用命令,查看當前進程中的線程的信息
ps H -eo pid,tid,%cpu | grep 93992
由上圖可知線程id為94012的線程的占用率最高
將線程號轉為16進制,并記住該16進制
printf "%x\n" 94012
最終定位
[root@mycentos local]# jstack 93992
執行jstack 93992 可以根據線程 id 找到有問題的線程,進一步定位到問題代碼的源碼行號
由此可以定位到紅框中可能出現錯誤的代碼信息,進而進一步解決問題