Linux系統線上故障排查的幾種技巧
無論是開發還是運維,和 Linux 打交道是每個技術人的日常。然而,性能優化、故障排查也是軟件系統中最有挑戰的工作之一,甭管看了多少資料和書,一旦涉及到解決具體問題,照樣兒一臉懵逼,比如:
- 流量高峰期,服務器 CPU 使用率過高報警,你登錄 Linux 上去 top 完之后,卻不知道怎么進一步定位,到底是系統 CPU 資源太少,還是程序并發部分寫得有問題?
- 系統并沒有跑什么吃內存的程序,但在敲完 free 命令之后,卻發現已經沒什么內存了,到底是哪里占用了內存?為什么?
- 一大早就收到 Zabbix 告警,你發現某臺存放監控數據的數據庫主機 CPU 的 I/O Wait 較高,該怎么辦?
下面,介紹幾個 CPU 使用率過高的排查技巧:
1、通過top命令定位占用cpu高的進程
執行top命令得到以下結果:

通過上圖可以明顯看出進程PID41843占用cpu過高,明顯存在問題,定位到了進程id。當然如果你想只觀察進程PID41843的CPU和內存以及負載情況,可以使用以下命令
- top -p 41843
結果如下:

2、通過top命令定位問題進程中每個線程占用cpu情況
通過問題進程中每個線程占用cpu情況使用可以使用如下命令:
- top -p 41843 -H
查看進程PID41843的每一個線程占用CPU情況,如圖。

由上圖明顯可以發現,線程PID41892CPU占用率***,接下來定位該線程的代碼是否出現異常導致cpu占用過高。
3、通過jstack 命令定位問題代碼
上一步發現PID41892占用的CPU過高,就將這個PID轉換成16進制,易知,PID41892轉化成16進制為a3a4。使用如下命令命令定位問題代碼:
- jstack 41892 | grep a3a4
輸出如下:
- "Thread" prio=10 tid=0x00007f950043e000 nid=0x54ee in test();
可以分析得到: 線程Thread下的wait()函數cpu使用率很高,查看源代碼中的test()函數代碼如下:

while循環無法結束,一直搶占cpu,導致程序cpu使用過高,修改代碼即可。
當然了,除了cpu以外,還有很多其它問題,這種類似的排查經驗只能從實踐中總結,原理書是不會告訴你這些的。幾年前,我自己學習那會兒也看了不少書,嘗試從網上找過些零零散散的資料。但說真的,Linux 性能優化是個系統工程,除了要學習那些基礎知識點之外,還有 2 點比較重要:
- 掌握性能優化的思路和方法,嘗試大量 Linux 性能工具
- 從學習到輸出,說白了就是不斷實踐,從實踐中總結經驗