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

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

本文作者:HelloGitHub-秦人

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

項目源碼地址://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 //alibaba.github.io/arthas/arthas-boot.jar
wget //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 //localhost:9000/getUserInfo,訪問內容如下:

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

在服務運行要測試的項目 demo-0.0.1-SNAPSHOT.jar

nohup java -jar demo-0.0.1-SNAPSHOT.jar & #後台運行
curl //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 //localhost:9000/getUserInfo,顯示如下內容:

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

四、總結

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

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

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

五、附錄


關注公眾號加入我們