在公司定位故障問題的時候,一般我們會採用在代碼中關鍵代碼中打印日誌,然後採用在環境容器內換 Jar 包的形式進行問題定位分析。但是這樣定位的問題流程很麻煩:
- 首先你要確保你打印日誌的全面性,萬一某個關鍵信息沒有打印出來你就需要重新打印、換包、重啟服務,一套流程下來浪費很多時間;
- 其次不是所有環境都運行換包和重啟服務
所以最近我一直在找更好的故障問題定位方法,然後我發現阿里開源的 Java 服務診斷工具好像還不錯,它可以查看方法調用入參、返回值,被調用的調用路徑、調用耗時、方法調用次數、成功次數、失敗次數等這些都可以記錄,所以學習記錄一下這個工具。
什麼是 arthas#
官方介紹:
Arthas 是一款線上監控診斷產品,通過全局視角實時查看應用 load、內存、gc、線程的狀態信息,並能在不修改應用代碼的情況下,對業務問題進行診斷,包括查看方法調用的出入參、異常,監測方法執行耗時,類加載信息等,大大提升線上問題排查效率。
運行環境#
- 只支持 JDK 6 + 的環境
- 由 Java 編寫的,支持跨平台:支持 Linux(主要)、Mac、Windows
特性#
- 採用命令行交互模式
- 提供
Tab
鍵自動補全的功能
初步使用#
因為平時公司使用的環境主要是在容器中,所以以下就主要記錄在 Linux 環境下如何使用這個工具
下載使用包#
由於公司環境是內網環境,不支持直接訪問連接 Github 進行安裝包的下載,這裡防止機器的網絡問題無法下載,所以採用的是手動先從 Github 下載拷貝到服務容器內部的方式進行使用
在 Github 中下載完整的安裝包,下載地址 :https://github.com/alibaba/arthas/releases
容器環境下解壓#
卸載#
定位完問題之後也要打掃好戰場,那卸載這個工具的方法也記錄一下
執行完以下三步即可卸載工具
運行#
首先啟動一個不會停止的 Java 程序服務,官方的安裝包下就附帶了一個給我們練手的 Jar 包:
math-game.jar
(不過一般我們的服務也是一直運行的,這裡就使用官方的包作為記錄)
然後再啟動 arthas
常用命令#
help#
dashboard#
儀表板:顯示當前系統的實時數據面板,平時沒有這個 dashboard 的時候我們一般只能通過 Linux 自帶的
top
命令查看系統運行的信息
輸入 dashboard,按 回車/enter
,會展示當前進程的信息,按 ctrl+c
或輸入 q
可以中斷執行。
顯示的信息大概分為 3 大塊:
- 最上面的是線程相關信息
- 中間區域是 JVM 內存相關的信息
- 最下面的是 Java 的運行環境信息
具體每一列的信息可以參考官方文檔
thread#
查看當前線程信息堆棧
當沒有參數時,顯示第一页線程的信息#
默認按照 CPU 增量時間降序排列,只顯示第一页數據。
支持一鍵展示當前最忙的前 N 個線程並打印堆棧#
thread --all, 顯示所有匹配的線程#
thread id, 顯示指定線程的運行堆棧#
thread -b, 找出當前阻塞其他線程的線程#
watch#
觀察指定方法的調用情況
可以觀察到:
方法返回值、入參、方法拋出的異常,還可以通過編寫 OGNL 表達式進行對應變量的查看
觀察函數調用返回時的參數、this 對象和返回值#
同時觀察函數調用前和函數返回後#
觀察當前對象中的屬性#
如果想查看函數運行前後,當前對象中的屬性,可以使用 target 關鍵字,target 代表當前對象,然後使用 target.field_name 訪問當前對象的某個屬性
trace#
方法內部調用路徑,並輸出路徑上的每個節點上耗時,服務間調用時間過長時使用
- 輸出結果中 #24 表示 在源文件的第 24 行調用了
primeFactors()
函數 - 輸出結果中 #25 表示 在源文件的第 25 行調用了
print()
函數
stack#
輸出當前方法被調用的調用路徑,當我們需要知道這個方法(被很多地方調用過)從那裡開始執行了就可以使用這個命令(適合尋根溯源)
jad#
反編譯指定已加載類的源碼,便於在線上理解業務邏輯,反編譯出來的代碼是帶語法高亮的