Arthas是Alibaba開源的Java診斷工具,深受開發(fā)者喜愛。
當(dāng)你遇到以下類似問題而束手無策時,Arthas可以幫助你解決:
- 這個類從哪個 jar 包加載的?為什么會報各種類相關(guān)的 Exception?
- 我改的代碼為什么沒有執(zhí)行到?難道是我沒 commit?分支搞錯了?
- 遇到問題無法在線上 debug,難道只能通過加日志再重新發(fā)布嗎?
- 線上遇到某個用戶的數(shù)據(jù)處理有問題,但線上同樣無法 debug,線下無法重現(xiàn)!
- 是否有一個全局視角來查看系統(tǒng)的運(yùn)行狀況?
- 有什么辦法可以監(jiān)控到JVM的實(shí)時運(yùn)行狀態(tài)?
- 怎么快速定位應(yīng)用的熱點(diǎn),生成火焰圖?
Arthas的功能非常多,這里只介紹一種:當(dāng)線上服務(wù)出現(xiàn)問題,已經(jīng)定位到是某些類有問題,但暫時不能重新部署,如何通過arthas快速熱更新。
注:重啟服務(wù)后會回到修改前的狀態(tài)
1 服務(wù)器下載arthas
1.1 從Maven倉庫下載
# 比如要下載3.x.x版本(替換3.x.x為最新版本),下載的url是:
https://maven.aliyun.com/repository/public/com/taobao/arthas/arthas-packaging/3.x.x/arthas-packaging-3.x.x-bin.zip
1.2 從Github Releases頁下載

image.png
1.3 我采用maven下載
wget https://maven.aliyun.com/repository/public/com/taobao/arthas/arthas-packaging/3.3.6/arthas-packaging-3.3.6-bin.zip

image.png
1.4 解壓
unzip arthas-packaging-3.3.6-bin.zip -d ./arthas

image.png
2 啟動一個springboot項(xiàng)目
簡單的springboot項(xiàng)目,只有一個hello接口。

image.png

image.png

image.png
3 啟動arthas

image.png
3.1 用as.sh啟動
解壓后,在文件夾里有as.sh,直接用./as.sh的方式啟動
./as.sh
3.2 用arthas-boot啟動
在解壓后,在文件夾里有arthas-boot.jar,直接用java -jar的方式啟動
java -jar arthas-boot.jar
啟動arthas后,會列出正在運(yùn)行的java進(jìn)程,輸入要測試項(xiàng)目前面的數(shù)字然后回車即可。

image.png
4 熱更新
4.1 jad
假設(shè)我們已定位到問題出在HelloController中的hello方法,用jad命令反編譯查看正在運(yùn)行的代碼(我們的代碼可能有很多git分支,線上不確定是運(yùn)行的哪個)

image.png

image.png

image.png

image.png

image.png
jad --source-only com.example.demo.controller.HelloController

image.png
4.2 修改代碼
- 用arthas的mc命令可以編譯java,但是有可能失敗;
- 也可以在本地生成.class文件上傳到服務(wù)器。
注:redefine命令和jad/watch/trace/monitor/tt等命令會沖突。執(zhí)行完redefine之后,如果再執(zhí)行上面提到的命令,則會把redefine的字節(jié)碼重置。 原因是jdk本身redefine和Retransform是不同的機(jī)制,同時使用兩種機(jī)制來更新字節(jié)碼,只有最后修改的會生效。

image.png
4.2.1 直接在服務(wù)器上修改

image.png
4.2.1.1 jad反編譯java代碼
jad --source-only com.example.demo.controller.HelloController > /usr/xzp/arthas/online/HelloController.java
4.2.1.2 用vim修改java文件

image.png
4.2.1.3 sc查找加載HelloController的類加載器

image.png

image.png
4.2.1.4 mc編譯

image.png

image.png
4.2.1.5 redefine熱更新

image.png

image.png
4.2.2 本地修改后上傳到服務(wù)器

image.png
4.2.2.1 本地修改代碼編譯生成.class文件

image.png
4.2.2.2 在本地先轉(zhuǎn)換.class文件為base64,再保存為result.txt
base64 < HelloController.class > result.txt

image.png
4.2.2.3 到服務(wù)器上,新建并編輯result.txt,復(fù)制本地的內(nèi)容,粘貼再保存
4.2.2.4 把服務(wù)器上的 result.txt還原為.class,用md5命令計(jì)算哈希值,校驗(yàn)是否一致.

image.png
4.2.2.5 redefine
redefine /usr/xzp/arthas/local/HelloController.class

image.png