本文適合有 Java 基礎知識的人群。
本文作者:HelloGitHub-秦人
HelloGitHub 推出的《講解開源專案》系列,今天給大家帶來一款阿里開源的 Java 診斷利器 Arthas 專案—— Arthas
一、簡介
為什麼要用 Arthas?好多 Java 開發的小夥伴可能有遇到下面這些問題:
-
專案中匯入了一個 jar 包的不同版本,那麼這個類從哪個 jar 包載入的?線上環境為什麼會報各種異常?
-
本地專案執行沒問題,線上環境執行的結果為什麼和本地不同?資料原因沒有執行到?程式碼沒有 commit?環境上使用的分支搞不對?
-
線上環境遇到偶先問題,難道只能通過加日誌,調整專案日誌級別,重新打包釋出驗證問題嗎?
-
線上環境遇到某個使用者的審批流程走的不對,線下環境無法重現,怎麼線上上進行遠端除錯呢?
-
有沒有一個監控系統的執行整體狀況的功能?
-
JDK 自帶了一些監控工具,本地可動態監控 JVM 執行狀態,那麼線上環境有什麼辦法可以監控到 JVM 的實時執行狀態?
-
線上上環境怎麼快速定位應用的熱點,生成火焰圖?
1.1 實現原理
整體巨集觀模組呼叫圖如下:
1.2 主要功能
Arthas 提供的功能主要可以分為以下三個方面:
- 資訊監控
- 程式執行基本資訊包括:記憶體、CPU佔用、執行緒資訊、執行緒堆疊、執行緒數統計、環境變數資訊。
- 物件資訊:類物件靜態屬性、 Mbean 的屬性資訊、已載入類資訊、類載入器、類方法資訊。
- 方法呼叫
- 方法呼叫入參、返回值檢視。
- 方法被呼叫的呼叫路徑、呼叫耗時、方法呼叫次數、成功次數、失敗次數等統計。
- 記錄和重做方法呼叫。
- 類檔案處理
- 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 還有更多強大的功能等待你的發現!
五、附錄
關注公眾號加入我們