banner
lMingyul

lMingyul

记录穿过自己的万物
jike
twitter
github
bilibili

用好系列-arthas之入門篇

在公司定位故障問題的時候,一般我們會採用在代碼中關鍵代碼中打印日誌,然後採用在環境容器內換 Jar 包的形式進行問題定位分析。但是這樣定位的問題流程很麻煩:

  • 首先你要確保你打印日誌的全面性,萬一某個關鍵信息沒有打印出來你就需要重新打印、換包、重啟服務,一套流程下來浪費很多時間;
  • 其次不是所有環境都運行換包和重啟服務

所以最近我一直在找更好的故障問題定位方法,然後我發現阿里開源的 Java 服務診斷工具好像還不錯,它可以查看方法調用入參、返回值,被調用的調用路徑、調用耗時、方法調用次數、成功次數、失敗次數等這些都可以記錄,所以學習記錄一下這個工具。

什麼是 arthas#

官方介紹:
Arthas 是一款線上監控診斷產品,通過全局視角實時查看應用 load、內存、gc、線程的狀態信息,並能在不修改應用代碼的情況下,對業務問題進行診斷,包括查看方法調用的出入參、異常,監測方法執行耗時,類加載信息等,大大提升線上問題排查效率。

運行環境#

  • 只支持 JDK 6 + 的環境
  • 由 Java 編寫的,支持跨平台:支持 Linux(主要)、Mac、Windows

特性#

  • 採用命令行交互模式
  • 提供 Tab 鍵自動補全的功能

初步使用#

因為平時公司使用的環境主要是在容器中,所以以下就主要記錄在 Linux 環境下如何使用這個工具

下載使用包#

由於公司環境是內網環境,不支持直接訪問連接 Github 進行安裝包的下載,這裡防止機器的網絡問題無法下載,所以採用的是手動先從 Github 下載拷貝到服務容器內部的方式進行使用

在 Github 中下載完整的安裝包,下載地址 :https://github.com/alibaba/arthas/releases

CleanShot-2023-04-30-00-13-53@2x

容器環境下解壓#

CleanShot-2023-04-30-00-44-29@2x

卸載#

定位完問題之後也要打掃好戰場,那卸載這個工具的方法也記錄一下

執行完以下三步即可卸載工具

運行#

首先啟動一個不會停止的 Java 程序服務,官方的安裝包下就附帶了一個給我們練手的 Jar 包:math-game.jar (不過一般我們的服務也是一直運行的,這裡就使用官方的包作為記錄)

然後再啟動 arthas

CleanShot-2023-04-30-00-50-48@2x


常用命令#

help#

dashboard#

儀表板:顯示當前系統的實時數據面板,平時沒有這個 dashboard 的時候我們一般只能通過 Linux 自帶的 top 命令查看系統運行的信息

輸入 dashboard,按 回車/enter,會展示當前進程的信息,按 ctrl+c 或輸入 q 可以中斷執行。
CleanShot-2023-04-30-01-01-50@2x

顯示的信息大概分為 3 大塊:

  • 最上面的是線程相關信息
  • 中間區域是 JVM 內存相關的信息
  • 最下面的是 Java 的運行環境信息
    具體每一列的信息可以參考官方文檔

thread#

查看當前線程信息堆棧

當沒有參數時,顯示第一页線程的信息#

默認按照 CPU 增量時間降序排列,只顯示第一页數據。

CleanShot-2023-05-03-11-59-07@2x

支持一鍵展示當前最忙的前 N 個線程並打印堆棧#

CleanShot-2023-05-03-12-00-56@2x 1

thread --all, 顯示所有匹配的線程#

CleanShot-2023-05-03-16-43-24@2x

thread id, 顯示指定線程的運行堆棧#

thread -b, 找出當前阻塞其他線程的線程#

watch#

觀察指定方法的調用情況
可以觀察到:
方法返回值、入參、方法拋出的異常,還可以通過編寫 OGNL 表達式進行對應變量的查看

觀察函數調用返回時的參數、this 對象和返回值#

同時觀察函數調用前和函數返回後#

觀察當前對象中的屬性#

如果想查看函數運行前後,當前對象中的屬性,可以使用 target 關鍵字,target 代表當前對象,然後使用 target.field_name 訪問當前對象的某個屬性

trace#

方法內部調用路徑,並輸出路徑上的每個節點上耗時,服務間調用時間過長時使用

  • 輸出結果中 #24 表示 在源文件的第 24 行調用了 primeFactors() 函數
  • 輸出結果中 #25 表示 在源文件的第 25 行調用了 print() 函數

stack#

輸出當前方法被調用的調用路徑,當我們需要知道這個方法(被很多地方調用過)從那裡開始執行了就可以使用這個命令(適合尋根溯源)

jad#

反編譯指定已加載類的源碼,便於在線上理解業務邏輯,反編譯出來的代碼是帶語法高亮的

CleanShot-2023-05-11-00-34-53@2x


參考資料#

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。