一、官方文檔
開源地址:https://github.com/alibaba/arthas
官方文檔:https://alibaba.github.io/arthas
二、命令介紹
1. Dashboard 實時數據 [i:]刷新實時數據的時間間隔 (ms),默認5000ms [n:]刷新實時數據的次數 2. Thread 查看當前線程信息,查看線程的堆棧 id 線程id [n:] 指定最忙的前N個線程並打印堆棧 [b] 找出當前阻塞其他線程的線程 [i <value>] 指定cpu占比統計的采樣間隔,單位為毫秒 3. Jad 反編譯指定已加載類的源碼 class-pattern 類名表達式匹配 [c:] 類所屬 ClassLoader 的 hashcode [E] 開啟正則表達式匹配,默認為通配符匹配 4. Jvm THREAD相關 COUNT: JVM當前活躍的線程數 DAEMON-COUNT: JVM當前活躍的守護線程數 PEAK-COUNT: 從JVM啟動開始曾經活着的最大線程數 STARTED-COUNT: 從JVM啟動開始總共啟動過的線程次數 DEADLOCK-COUNT: JVM當前死鎖的線程數 文件描述符相關 MAX-FILE-DESCRIPTOR-COUNT:JVM進程最大可以打開的文件描述符數 OPEN-FILE-DESCRIPTOR-COUNT:JVM當前打開的文件描述符數 5. Classloader [l] 按類加載實例進行統計 [t] 打印所有ClassLoader的繼承樹 [a] 列出所有ClassLoader加載的類,請謹慎使用 [c:] ClassLoader的hashcode [classLoaderClass:] 指定執行表達式的 ClassLoader 的 class name [c: r:] 用ClassLoader去查找resource [c: load:] 用ClassLoader去加載指定的類 6. Logger logger --name ROOT --level debug 修改日志級別 logger -n org.springframework.web 查看指定名字的logger信息 logger -c 2a139a55 查看指定classloader的logger信息 7. Sysprop 查看當前JVM的系統屬性 Sysprop 查看所有 Sysprop <property-name> <property-value> 修改單個 8. Sysenv 查看當前JVM的環境屬性 Sysenv 查看所有 Sysenv <env-name> 查看單個 9. Vmoption 查看,更新VM診斷相關的參數 vmoption [name] [value] 更新 10.Perfcount 查看當前JVM的 Perf Counter性能統計信息 11. Mbean 便捷的查看或監控 Mbean 的屬性信息 MBean其實也是JavaBean的一種,但是MBean往往代表的是JMX中的一種可以被管理的資源。 MXBean與MBean的區別主要是在於在接口中會引用到一些其他類型的類時,其表現方式的不一樣。在MXBean中,如果一個MXBean的接口定義了一個屬性是一個自定義類型,如MemoryMXBean中定義了heapMemoryUsage屬性,這個屬性是MemoryUsage類型的,當JMX使用這個MXBean時,這個MemoryUsage就會被轉換成一種標准的類型,這些類型被稱為開放類型,是定義在javax.management.openmbean包中的。而這個轉換的規則是,如果是原生類型,如int或者是String,則不會有變化,但如果是其他自定義類型,則被轉換成CompositeDataSupport類。 MBean, MXBean接口后綴,被實現類去掉后綴。 12. Ognl express 執行的表達式 [c:] 執行表達式的 ClassLoader 的 hashcode,默認值是SystemClassLoader [classLoaderClass:] 指定執行表達式的 ClassLoader 的 class name [x] 結果對象的展開層次,默認值1 查看靜態變量,可調用靜態方法 ognl '@com.shunwang.buss.agent.client.config.AgentApiConfig@APPLICATION_NAME‘ 執行多行表達式,賦值給臨時變量,返回一個List: ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}' 13. Sc 查看JVM已加載的類信息 參數名稱 參數說明 class-pattern 類名表達式匹配 method-pattern 方法名表達式匹配 [d] 輸出當前類的詳細信息,包括這個類所加載的原始文件來源、類的聲明、加載的ClassLoader等詳細信息。 如果一個類被多個ClassLoader所加載,則會出現多次 [E] 開啟正則表達式匹配,默認為通配符匹配 [f] 輸出當前類的成員變量信息(需要配合參數-d一起使用) [x:] 指定輸出靜態變量時屬性的遍歷深度,默認為 0,即直接使用 toString 輸出 [c:] 指定class的 ClassLoader 的 hashcode [classLoaderClass:] 指定執行表達式的 ClassLoader 的 class name [n:] 具有詳細信息的匹配類的最大數量(默認為100) 14. Sm 查看已加載類的方法信息 class-pattern 類名表達式匹配 method-pattern 方法名表達式匹配 [d] 展示每個方法的詳細信息 [E] 開啟正則表達式匹配,默認為通配符匹配 [c:] 指定class的 ClassLoader 的 hashcode [classLoaderClass:] 指定執行表達式的 ClassLoader 的 class name [n:] 具有詳細信息的匹配類的最大數量(默認為100) 15. dump 已加載類的 bytecode 到特定目錄 16. Heapdump 類似jmap命令的heap dump功能 heapdump --live /tmp/dump.hprof 只dump live對象 17. tt 方法執行數據的時空隧道,記錄下指定方法每次調用的入參和返回信息,並能對這些不同的時間下調用進行觀測 -t 記錄下來每次執行情況 -n 指定記錄的次數 TIMESTAMP 方法執行的本機時間,記錄了這個時間片段所發生的本機時間 IS-RET 方法是否以正常返回的形式結束 IS-EXP 方法是否以拋異常的形式結束 OBJECT 執行對象的hashCode() 解決方法重載: tt -t *Test print params.length==1 tt -t *Test print 'params[1] instanceof Integer' 解決指定參數: tt -t *Test print params[0].mobile=="13989838402" 構成條件表達式的 Advice 對象: https://arthas.aliyun.com/doc/advice-class.html tt -l 檢索調用記錄 tt -s 'method.name=="primeFactors"' -i [index] 查看詳細信息 tt -i 1004 -p 重做一次調用(threadlocal信息會丟失,引用對象入參可能會變更) 18. stack 輸出當前方法被調用的調用路徑 class-pattern 類名表達式匹配 method-pattern 方法名表達式匹配 condition-express 條件表達式 [E] 開啟正則表達式匹配,默認為通配符匹配 [n:] 執行次數限制 例子: stack demo.Test test 'params[0]<0' -n 2 執行時間過濾:'#cost>5' 19. trace 方法內部調用路徑,並輸出方法路徑上的每個節點上耗時 class-pattern 類名表達式匹配 method-pattern 方法名表達式匹配 condition-express 條件表達式 [E] 開啟正則表達式匹配,默認為通配符匹配 [n:] 命令執行次數 #cost 方法執行耗時 深入子函數: a.新開終端telnet localhost 3658 b.trace demo.MathGame primeFactors --listenerId 3 20. monitor 方法實時監控 monitor -c 5 demo.Test test 21. watch 方法執行數據觀測 class-pattern 類名表達式匹配 method-pattern 方法名表達式匹配 express 觀察表達式 condition-express 條件表達式 [b] 在方法調用之前觀察 [e] 在方法異常之后觀察 [s] 在方法返回之后觀察 [f] 在方法結束之后(正常返回和異常返回)觀察 [E] 開啟正則表達式匹配,默認為通配符匹配 [x:] 指定輸出結果的屬性遍歷深度,默認為 1 觀察出參:watch demo.Test test "{params,returnObj}" -x 2 入參: -b 條件表達式:watch demo.Test test "{params[0],target}" "params[0]<0" 異常: "{params[0],throwExp}" -e 22. profiler 不斷采樣生成火焰圖 23.支持基本命令:cat,echo,grep,pwd 24. tee 類似傳統的tee命令, 用於讀取標准輸入的數據,並將其內容輸出成文件。 sysprop | tee /path/to/logfile | grep java sysprop | tee -a /path/to/logfile | grep java 25. options 全局開關 26. 基礎命令 reset——重置增強類,將被 Arthas 增強過的類全部還原,Arthas 服務端關閉時會重置所有增強過的類 history——打印命令歷史 quit——退出當前 Arthas 客戶端,其他 Arthas 客戶端不受影響 stop——關閉 Arthas 服務端,所有 Arthas 客戶端全部退出 27. mc Memory Compiler/內存編譯器,編譯.java文件生成.class。 -c 指定classloader -d 指定輸出目錄 28. redefine 加載外部的.class文件,redefine jvm已加載的類。 注意, redefine后的原來的類不能恢復.不允許新增加field/method,正在跑的函數,沒有退出不能生效. reset命令對redefine的類無效。如果想重置,需要redefine原始的字節碼 redefine命令和jad/watch/trace/monitor/tt等命令會沖突。執行完redefine之后,如果再執行上面提到的命令,則會把redefine的字節碼重置。
三、如何開始
- 下載啟動:
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
2. 遠程連接:arthas tunnel server
wget https://github.com/alibaba/arthas/releases/download/arthas-all-3.3.9/arthas-tunnel-server-3.3.9.jar
java -jar arthas-tunnel-server.jar
默認情況下,arthas tunnel server的web端口是8080,arthas agent連接的端口是7777。
通過Spring Boot的Endpoint,可以查看到具體的連接信息: http://localhost:8080/actuator/arthas
-
-
啟動arthas時連接到tunnel server
-
as.sh --tunnel-server 'ws://192.168.42.157:7777/ws'
-
-
springboot應用
-
依賴:
啟動監聽自身:
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-spring-boot-starter</artifactId>
<version>3.3.9</version>
</dependency>
配置:連接到tunnel server
arthas.agent-id=sadsadsada
arthas.tunnel-server=ws://192.168.42.157:7777/ws
四、實踐
- 實時代碼更新:
jad --source-only demo.Test > /tmp/Test.java
修改Test.java
sc -d *Test | grep classLoaderHash 查看類加載hash
mc -c [hash值] /tmp/Test.java -d /tmp 編譯
redefine /tmp/demo/Test.class 生效
2. 修改屬性值:

3. 修改日志屬性:
ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader '@com.example.demo.arthas.user.UserController@logger.setLevel(@ch.qos.logback.classic.Level@DEBUG)'
4. 追蹤排查問題:
trace javax.servlet.Filter * 追蹤所有Filter函數
trace javax.servlet.Servlet * > /tmp/servlet.txt
401:
Access is denied
throw:
5. 查看5秒內的CPU使用率top n線程棧
thread -n 3 -i 5000
查找線程是否有阻塞
thread -b