傳統排查問題
-
1 top
通過top命令發現,發現某個進程的CPU和內存使用率過高。獲取到進程Id後可以通過以下命令來進行錯誤排查
通過top -Hp pid可以查看該進程下各個線程的cpu使用情況;
-
2 jinfo
利用jinfo pid 查詢當前java進程詳情,比如跑的進程詳細信息,jvm參數等。
-
3 jstat
jstat gcacuse pid time(毫秒) 查詢當前進程GC情況。
-
4 jmap
jmap -heap pid 查詢當前進程jvm內存分配情況。
jmap -histo:live pid 顯示堆中對象統計信息,類,實例數量,合計容量。
想要暴力獲取堆轉儲快照還有一些暴力的手段比如設置 -XX:+HeapDumpOnOutOfMemoryError參數,可以讓虛擬機在內存溢出異常出現之後自動生成堆轉儲快照文件。
-
5 jstack
jstack pid(線程Id) 查詢當前線程的堆棧狀態
jstack命令生成的thread dump信息包含了JVM中所有存活的線程,在top命令中,獲取到了佔用cpu資源較高的線程pid,將該pid轉成16進制的值,在thread dump中每個線程都有一個nid,找到對應的nid即可;隔段時間再執行一次stack命令獲取thread dump,區分兩份dump是否有差別,得到這個信息,就可以檢查對應的代碼是否有問題
進階版排查問題
在這裏,不得不提到一款十分優秀的開源Java診斷工具,大名鼎鼎的Arthas。具體有多麼強大,看一下官方解釋
當你遇到以下類似問題而束手無策時,Arthas可以幫助你解決:
1、這個類從哪個 jar 包加載的?爲什麼會報各種類相關的 Exception?
2、我改的代碼爲什麼沒有執行到?難道是我沒 commit?分支搞錯了?
3、遇到問題無法在線上 debug,難道只能通過加日誌再重新發布嗎?
4、線上遇到某個用戶的數據處理有問題,但線上同樣無法 debug,線下無法重現!
5、是否有一個全局視角來查看系統的運行狀況?
6、有什麼辦法可以監控到JVM的實時運行狀態?
那麼問題來了,Arthas怎麼用?
-
安裝
Github下載即可
-
運行
java -jar arthas-boot.jar
輸入對應JAVA進程編號,進行診斷
-
使用
接下來就可以使用arthas命令了
-
dashboard 顯示當前系統的實時數據面板(線程,內存,GC信息,運行時環境信息)
-
thread id 顯示指定線程的運行堆棧
-
sc 查看 JVM 已加載的類詳細信息
-
sm 查看已加載類的方法信息。
-
jad 反編譯指定已加載類的源代碼。(可以用來排查代碼是否正確上線)
-
trace 顯示方法內部調用路徑,非實時返回,輸出方法路徑上的總耗時,和每個節點上的詳細耗時。
-
jad 反編譯指定已加載類的源代碼。(可以用來排查代碼是否正確上線)
-
Ognl 動態執行代碼(可以調用static函數,靜態類靜態字段,執行表達式賦值給臨時變量)
-
redafine 該命令可以加載外部的.class文件,然後覆蓋jvm已加載的類。用於緊急修復時使用
-
quit/exit 退出當前 Arthas。
這個命令僅退出當前連接的客戶端,附到目標進程上的 Arthas 會繼續運行,端口不會關閉,下次連接時可以直接連接使用。
-
寫在最後
arthas其他命令就不一一列舉了,大家可以用過help能看到所有命令,並且每個命令都有詳細的說明。