Alibaba應用診斷利器Arthas 3.0.5版本釋出:提升全平臺使用者體驗
Arthas從9月份開源以來,受到廣大Java開發者的支援,Github Star數三個月超過6000,非常感謝使用者支援。同時使用者給Arthas提出了很多建議,其中反映最多的是:
- Windows平臺使用者體驗不好
- Attach的程序和最終連線的程序不一致
- 某些環境下沒有安裝Telnet,不能連線到Arthas Server
- 本地啟動,不需要下載遠端(很多公司安全考慮)
- 下載速度慢(預設從maven central repository下載)
在Arthas 3.0.5版本里,我們在使用者體驗方面做了很多改進,下面逐一介紹。
- 文件: ofollow,noindex">alibaba.github.io/arthas/
- Github: github.com/alibaba/art…
- Gitee: gitee.com/arthas/arth…
全平臺通用的arthas-boot
arthas-boot
是新增加的支援全平臺的啟動器,Windows/Mac/Linux下使用體驗一致。下載後,直接 java -jar
命令啟動:
wget https://alibaba.github.io/arthas/arthas-boot.jar java -jar arthas-boot.jar 複製程式碼
arthas-boot
的功能比以前的 as.sh
更強大。
-
比如下載速度比較慢,可以指定阿里雲的映象。
java -jar arthas-boot.jar --repo-mirror aliyun --use-http 複製程式碼
-
比如可以通過
session-timeout
指定超時時間:java -jar arthas-boot.jar --session-timeout 3600 複製程式碼
-
更多的功能可以通過
java -jar arthas-boot.jar -h
檢視
arthas-boot
在attach成功之後,會啟動一個java telent client去連線Arthas Server,使用者沒有安裝telnet的情況下也可以正常使用。
優先使用當前目錄的Arthas
在新版本里,預設會從 arthas-boot.jar
和 as.sh
所在的目錄下查詢arthas home,這樣子使用者全量安裝之後,不需要再從遠端下載Arthas。
- 使用者可以更方便地整合到自己的基礎映象,或者docker映象裡
- 對安全要求嚴格的公司,不用再擔心從遠端下載的問題
Attach之前先檢測埠
在之前的版本里,使用者困擾最多的是,明明選擇了程序A,但是實際連線到的卻是程序B。
原因是之前attach了程序B,沒有執行 shutdown
,下次再執行時,還是連線到程序B。
在新版本里,做了改進:
- 在attach之前,檢測使用3658埠的程序
- 在Attach時,如果埠和程序不匹配,會打印出ERROR資訊
$ java -jar arthas-boot.jar [INFO] Process 1680 already using port 3658 [INFO] Process 1680 already using port 8563 * [1]: 1680 Demo [2]: 35542 [3]: 82334 Demo 3 [ERROR] Target process 82334 is not the process using port 3658, you will connect to an unexpected process. [ERROR] If you still want to attach target process 82334, Try to set a different telnet port by using --telnet-port argument. [ERROR] Or try to shutdown the process 1680 using the telnet port first. 複製程式碼
更好的歷史命令匹配功能
-
新版本對鍵盤
Up/Down
有了更好的匹配機制,試用有驚喜:)比如執行了多次trace,但是在命令列輸入 trace後,想不起來之前trace的具體類名,那麼按
Up
,可以很輕鬆地匹配到之前的歷史命令,不需要辛苦翻頁。 -
新版本增加了
history
命令
改進Web Console的體驗
-
改進對Windows的字型支援
之前Windows下面使用的是非等寬字型,看起來很難受。新版本里統一為等寬字型。
-
增大字型,不再傷害眼睛

新增sysenv命令
sysenv命令和sysprop類似,可以列印JVM的環境變數。
新增ognl命令
ognl命令提供了單獨執行ognl指令碼的功能。可以很方便呼叫各種程式碼。
比如執行多行表示式,賦值給臨時變數,返回一個List:
$ ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}' @ArrayList[ @String[/opt/java/8.0.181-zulu/jre], @String[OpenJDK Runtime Environment], ] 複製程式碼
watch命令列印耗時,更方便定位效能瓶頸
之前watch命令只支援列印入參返回值等,新版本同時打印出呼叫耗時,可以很方便定位效能瓶頸。
$ watch demo.MathGame primeFactors 'params[0]' Press Ctrl+C to abort. Affect(class-cnt:1 , method-cnt:1) cost in 22 ms. ts=2018-11-29 17:53:54; [cost=0.131383ms] result=@Integer[-387929024] ts=2018-11-29 17:53:55; [cost=0.132368ms] result=@Integer[-1318275764] ts=2018-11-29 17:53:56; [cost=0.496598ms] result=@Integer[76446257] ts=2018-11-29 17:53:57; [cost=4.9617ms] result=@Integer[1853966253] 複製程式碼
改進類搜尋匹配功能,更好支援lambda和內部類
之前的版本里,在搜尋lambda類時,或者反編繹lambda類有可能會失敗。新版本做了修復。比如
$ jad Test$$Lambda$1/1406718218 ClassLoader: +-sun.misc.Launcher$AppClassLoader@5c647e05 +-sun.misc.Launcher$ExtClassLoader@3c1491ce Location: /tmp/classes /* * Decompiled with CFR 0_132. * * Could not load the following classes: *Test *Test$$Lambda$1 */ import java.lang.invoke.LambdaForm; import java.util.function.Consumer; final class Test$$Lambda$1 implements Consumer { private Test$$Lambda$1() { } @LambdaForm.Hidden public void accept(Object object) { Test.lambda$0((Integer)((Integer)object)); } } 複製程式碼