應用伺服器CPU高效能定位和排查
本課程的主旨及目標
•導致應用CPU高的常見原因
•定位問題的大體思路
•定位問題的具體方法
•實際案例
應用CPU高常見原因
•1.程式計算比較密集
•2. 程式死迴圈、死鎖
•3.程式邏請求堵塞
•4.IO讀寫太高 (df –h看看磁碟是不是滿了)
•5.自創執行緒沒有限制(執行緒池)
•6.不合理的建立物件,導致頻繁GC
定位問題的具體方法
1.不管什麼情況先用top命令檢視資源消耗,找到消耗大量CPU資源的程序pid,我們一般都是java程序排名第一
2.輸入top –p pid 來單獨監控該程序
3.在第2步的監控介面輸入H,獲取當前程序下的所有執行緒資訊
4.找到消耗cpu特別高的執行緒編號(可能會有多個),這裡是6752
5.將第4步得到的執行緒編號6752轉成16進位制是1a60,因為jstack輸出的執行緒棧資訊中,執行緒ID是以十六進位制展示的。
6.切換到jbossuser使用者【pid對應的程序使用者,這裡一般是java程序使用者】
7.因為沒有jstack這個檔案的環境變數,所以要先export PATH="$PATH:/opt/wildfly/openjdk/openjdk-1.8.0_92/bin"
8.使用命令 jstack $pid | grep “執行緒id” –A 30,把資訊打印出來【這裡的-A 30指的是30行】【執行緒id:根據第5步得到的1a68在pid執行緒資訊裡面去找對應執行緒內容】,也可以寫到檔案中,下載下來,通過16進位制的執行緒id來搜尋定位程式碼段。
9.通過jstack命令來檢視下當前記憶體狀態,解讀執行緒資訊,定位具體程式碼位置,接下來就是找開發人員確認問題,看這段程式碼是否可以優化。
實際案例
案例一:
定位到cpu過高是IO讀寫太高 ,接下來就是找開發人員確認這段程式碼是否可以優化
案例二:
兩個執行緒執行過程中,需要對兩個物件進行加鎖,且加鎖的順序不一致,導致了死鎖的產生,簡單的修復方法是:對兩個物件的加鎖順序一致。
注意:必須有兩個可以被加鎖的物件才能產生死鎖,只有一個不會產生死鎖問題
案例三:
案例四:
案例五:
1.生產環境heap堆記憶體不斷上升導致oom,pst環境復現heap堆記憶體不斷上升。經過分析堆記憶體建立的windq主題或佇列WindqQueue、WindqTopic方式會快取到連線工廠,快取的物件並不是根據唯一的key去快取,而是直接使用物件的引用作快取,導致jvm無法回收這部分記憶體(比如新建同一個sendOperationTopic的主題Object1,Object2,Object1和Object2都會快取到連線工廠)。
2.pst環境百萬資料重試發現棧記憶體溢位,由於遞迴呼叫導致,已將遞迴方法修改為迴圈的方式去呼叫。
結果:修改後pst環境記憶體回收穩定,無連線工廠大物件,堆記憶體,無棧記憶體溢位,cpu使用情況穩定。
發現程式異常前通過執行指令,直接生成當前JVM的dump檔案,15434是指JVM的程序號
jmap -dump:format=b,file=serviceDump.dat 15434