帶你上手阿里開源的 Java 診斷利器:Arthas

削微寒發表於2020-07-20

本文適合有 Java 基礎知識的人群。

本文作者:HelloGitHub-秦人

HelloGitHub 推出的《講解開源專案》系列,今天給大家帶來一款阿里開源的 Java 診斷利器 Arthas 專案—— Arthas

專案原始碼地址:https://github.com/alibaba/arthas

一、簡介

為什麼要用 Arthas?好多 Java 開發的小夥伴可能有遇到下面這些問題:

  • 專案中匯入了一個 jar 包的不同版本,那麼這個類從哪個 jar 包載入的?線上環境為什麼會報各種異常?

  • 本地專案執行沒問題,線上環境執行的結果為什麼和本地不同?資料原因沒有執行到?程式碼沒有 commit?環境上使用的分支搞不對?

  • 線上環境遇到偶先問題,難道只能通過加日誌,調整專案日誌級別,重新打包釋出驗證問題嗎?

  • 線上環境遇到某個使用者的審批流程走的不對,線下環境無法重現,怎麼線上上進行遠端除錯呢?

  • 有沒有一個監控系統的執行整體狀況的功能?

  • JDK 自帶了一些監控工具,本地可動態監控 JVM 執行狀態,那麼線上環境有什麼辦法可以監控到 JVM 的實時執行狀態?

  • 線上上環境怎麼快速定位應用的熱點,生成火焰圖?

1.1 實現原理

整體巨集觀模組呼叫圖如下:

1.2 主要功能

Arthas 提供的功能主要可以分為以下三個方面:

  1. 資訊監控
    • 程式執行基本資訊包括:記憶體、CPU佔用、執行緒資訊、執行緒堆疊、執行緒數統計、環境變數資訊。
    • 物件資訊:類物件靜態屬性、 Mbean 的屬性資訊、已載入類資訊、類載入器、類方法資訊。
  2. 方法呼叫
    • 方法呼叫入參、返回值檢視。
    • 方法被呼叫的呼叫路徑、呼叫耗時、方法呼叫次數、成功次數、失敗次數等統計。
    • 記錄和重做方法呼叫。
  3. 類檔案處理
    • dump 已載入類的位元組碼、位元組碼反編譯、類編譯、類重新熱載入。

二、安裝和使用

2.1 Linux 環境使用

登入 Linux 環境,下載 arthas-boot.jar,然後使用命令 java -jar xxx.jar 直接執行 jar 包。

下面兩個命令效果一樣,都可以下載。

curl -O https://alibaba.github.io/arthas/arthas-boot.jar
wget https://alibaba.github.io/arthas/arthas-boot.jar

進入 Arthas 第一步需要選擇專案

2.2 Docker 環境使用

進入一個之前已經啟動的 Docker 容器,這裡我進入了 tomcat7 容器。

docker ps -a #檢視所有容器
docker cp arthas-boot.jar tomcat7:/home #拷貝 jar 到容器 home 目錄
docker exec -it tomcat7 bash #進入名稱叫 tomcat7 的容器
cd /home 
java -jar arthas-boot.jar #執行 jar 包

注意:選擇的 Docker 容器必須是以 JDK 為基礎依賴構建的。

在命令列輸入 dashboard 就可以進入儀表板的所有資料。

2.3 在開發工具 IntelliJ IDEA 使用

Cloud Toolkit 是一個 IDE 外掛,幫助開發者更高效地開發、測試、診斷並部署應用。方便地將本地應用一鍵部署到任意機器,或 ECS、EDAS、Kubernetes。這裡只介紹一下連線遠端伺服器,使用 Arthas。

2.3.1 安裝外掛

File->Settings->Plugins 搜尋 Alibaba Cloud Toolkit

外掛安裝完重啟 IDEA。

2.3.2 使用工具

新增遠端伺服器,如下圖操作:

伺服器配置成功後,選擇 More->Diagnostic 即可連線到伺服器上。

2.3.3 執行效果

三、實戰案例分析

以線上程式碼熱更新,這裡我寫了一個小的 Sprinboot 專案,主要就是一個獲取學習資訊的介面。

@RestController
public class StudentConroller {

   @GetMapping("getUserInfo")
   public Student getUserInfo() {
      return new Student("小劉",12,"西安市雁塔區");
   }
}

通過 curl http://localhost:9000/getUserInfo,訪問內容如下:

{"name":"小劉","id":12,"address":"西安市雁塔區"}

在服務執行要測試的專案 demo-0.0.1-SNAPSHOT.jar

nohup java -jar demo-0.0.1-SNAPSHOT.jar & #後臺執行
curl http://localhost:9000/getUserInfo #訪問介面

執行 Arthas 主程式 arthas-boot.jar,選擇進入demo-0.0.1-SNAPSHOT.jar

使用 jad 反編譯 StudentConroller.java 程式碼

jad --source-only com.example.demo.controller.StudentConroller > /tmp/StudentConroller.java

開啟 /tmp/StudentConroller.java 下的檔案,修改反編繹出來的程式碼,修改內容如下:

@RestController
public class StudentConroller {
   @GetMapping(value={"getUserInfo"})
   public Student getUserInfo() {
      return new Student("小劉1", 122, "西安市高新區");
   }
}
  • sc 命令查詢載入 StudentConroller 的 ClassLoader

    $ sc -d *StudentConroller | grep classLoaderHash
    classLoaderHash   2e0fa5d3
    
  • mc 命令記憶體編繹程式碼

    $ mc -c 2e0fa5d3 /tmp/StudentConroller.java -d /tmp
    Memory compiler output:/tmp/com/example/demo/arthas/user/controller/StudentConroller.class
    Affect(row-cnt:1) cost in 346 ms
    
  • redefine 命令熱更新程式碼

    $ redefine /tmp/com/example/demo/controller/StudentConroller.class
    redefine success, size: 1
    
  • 檢測熱更新結果
    再次訪問 curl http://localhost:9000/getUserInfo,顯示如下內容:

用 Arthas 的 jad/mc/redefine 一條龍命令來線上熱更新程式碼非常強大,但也很危險,要做好許可權管理哦。

四、總結

本文開頭講 Arthas 有什麼作用、我們為什麼要用它。接著講了三種場景是如何使用 Arthas。最後以 Java 程式碼線上熱部署為例,感受了 Arthas 的強大。看到這裡我想你也對 Arthas 工具有了一個簡單的認識。

現在的趨勢開發人員做了久了慢慢就變為 DevOps,瞭解更多的底層邏輯也能更好的反饋到程式碼層面的上層建築

本文只能帶大家入門,Arthas 還有更多強大的功能等待你的發現!

五、附錄


關注公眾號加入我們

相關文章