面試官:應用上線後Cpu使用率飆升如何排查?
大家好,我是飄渺。
上次面試官問了個問題:應用上線後Cpu使用率飆升如何排查?
其實這是個很常見的問題,也非常簡單,那既然如此我為什麼還要寫呢?因為上次回答的時候我忘記將線程PID轉換成16進制的命令了。
所以我決定再重温一遍這個問題,當然貼心的我還給大家準備好了測試代碼,大家可以實際操作一下,這樣下次就不會忘記了。
模擬一個高CPU場景
```java
public class HighCpuTest {
public static void main(String[] args) {
List
Thread highCpuThread = new Thread(()->{
int i = 0;
while (true){
HignCpu cpu = new HignCpu("Java日知錄",i);
cpus.add(cpu);
System.out.println("high cpu size:" + cpus.size());
i ++;
}
});
highCpuThread.setName("HignCpu");
highCpuThread.start();
}
} ```
在main方法中開啟了一個線程,無限構建HighCpu
對象。
java
@Data
@AllArgsConstructor
public class HignCpu {
private String name;
private int age;
}
準備好上面的代碼,運行HighCpuTest,然後就可以開始一些列的操作來發現問題原因了。
排查步驟
第一步,使用 top 找到佔用 CPU 最高的 Java 進程
```shell 1. 監控cpu運行狀,顯示進程運行信息列表 top -c
- 按CPU使用率排序,鍵入大寫的P P ```
第二步,用 top -Hp
命令查看佔用 CPU 最高的線程
上一步用 top
命令找到了那個 Java 進程。那一個進程中有那麼多線程,不可能所有線程都一直佔着 CPU 不放,這一步要做的就是揪出這個罪魁禍首,當然有可能不止一個。
執行top -Hp pid
命令,pid 就是前面的 Java 進程,我這個例子中就是 16738
,完整命令為:
top -Hp 16738
,然後鍵入P (大寫p),線程按照CPU使用率排序
執行之後的效果如下
查到佔用CPU最高的那個線程 PID 為 16756
第三步,查看堆棧信息,定位對應代碼
通過printf命令將其轉化成16進制,之所以需要轉化為16進制,是因為堆棧裏,線程id是用16進製表示的。(我當時就是忘記這個命令了~)
shell
[root@review-dev ~]# printf "%x\n" 16756
4174
得到16進制的線程ID為4174。
通過jstack命令查看堆棧信息
shell
jstack 16738 | grep '0x4174' -C10 --color
如上圖,找到了耗CPU高的線程對應的線程名稱“HighCpu”,以及看到了該線程正在執行代碼的堆棧。
最後,根據堆棧裏的信息,定位到對應死循環代碼,搞定。
小結
cpu使用率飆升後如何排查這個問題不僅面試中經常會問,而且在實際工作中也非常有用,大家最好根據上述步驟實際操作一下,這樣才能記得住記得牢。
我正在參與掘金技術社區創作者簽約計劃招募活動,點擊鏈接報名投稿。
- 數據權限就該這麼實現(設計篇)
- 數據權限就該這麼實現(實現篇)
- 給你一段SQL,你會如何優化?
- 當我把ChatGPT機器人拉到微信羣裏,羣友都玩瘋了!!
- SpringBoot 如何保證接口安全?老鳥們都是這麼玩的!
- 掌握系統思維,你就可以既勤奮努力又輕鬆愉快。
- SpringBoot自定義註解 AOP 防止重複提交(建議收藏)
- 面試官:應用上線後Cpu使用率飆升如何排查?
- SpringBoot中實現業務校驗,這種方式才叫優雅!
- SpringCloud Gateway 收集輸入輸出日誌
- 震驚,Spring官方推薦的@Transational還能導致生產事故?
- 為什麼要在MVC三層架構上再加一層Manager層?
- SpringBoot 如何生成接口文檔,老鳥們都這麼玩的!
- SpringBoot 如何進行限流?老鳥們都這麼玩的!
- SpringBoot 生成接口文檔,我用smart-doc,一款比Swagger更nice的工具!
- SpringBoot 如何進行對象複製,老鳥們都這麼玩的!
- 3天,我把MySQL索引、鎖、事務、分庫分表擼乾淨了!
- 字節全面對外開放中台能力!中台,又靈了?
- 基於 Kubernetes 的微服務項目設計與實現
- 老闆要我開發一個簡單的工作流引擎