本文適合有 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 還有更多強大的功能等待你的發現!
五、附錄
關注公眾號加入我們