大家好,我是小悟

前言
日常開發(fā)過程中,可能會遇到小問題,本地代碼改完后,總得重新打包部署,線上代碼才會生效,這樣太麻煩了,這個時候就可以考慮使用Arthas(阿爾薩斯)工具來熱更新線上代碼,先使線上的功能能使用,后面有大的迭代版本的時候再打包部署。筆者使用了這個工具,發(fā)現(xiàn)這個操作實在是太好用了,在此做下筆記,以供后續(xù)參考。
示例
本文示例根據(jù)項目打包部署的格式不同分為兩種情況,一種是jar包,一種是war包。
本文以 Arthas 3.3.3 版本為例,主要使用到 jad/sc/mc/redefine 三個指令。
首先,下載 arthas-boot.jar,進(jìn)入服務(wù)器某個目錄下,比如是/data/下,執(zhí)行
2、啟動:java -jar arthas-boot.jar
1、jar包的情況:
進(jìn)入服務(wù)器某個目錄下,比如是/data/下,下載官方demo并啟動
arthas-demo是一個簡單的程序,每隔一秒生成一個隨機數(shù),再執(zhí)行質(zhì)因數(shù)分解,并打印出分解結(jié)果,我們想要熱更新代碼,在打印的信息上加上“打印出信息來看===”這幾個字。
1、下載:curl -O https://alibaba.github.io/arthas/arthas-demo.jar
2、啟動:java -jar arthas-demo.jar

/data/下,下載arthas并啟動
2、啟動:java -jar arthas-boot.jar

找到我們要熱更新代碼的項目,比如輸入2,回車

Arthas 修改熱更的邏輯主要分為三步:
jad 命令反編譯出內(nèi)存中的字節(jié)碼,生成 class 文件
修改代碼,使用 mc 命令內(nèi)存編譯新的 class 文件
redefine 重新加載新的 class 文件
從而達(dá)到熱更新的效果
jad反編譯
控制臺輸入,注意,--source-only后面的文件路徑,開始是從/src/main/java/下面開始的,比如 com.xxx.xxx
jad --source-only demo.MathGame > MathGame.java
在/data/下面會生成MathGame.java文件,我們用開發(fā)工具或者vi命令打開修改MathGame.java內(nèi)容,在打印的語句里面加上“打印出信息來看===”這幾個字保存
sc 查找類加載器hash值
控制臺輸入
sc -d demo.MathGame

classLoaderHash這個字段就是hash值
sc -d demo.MathGame | grep classLoaderHash
mc 內(nèi)存編譯
結(jié)果:Memory compiler output:
/data/demo/MathGame.class
redefine 熱更新代碼
執(zhí)行:redefine /data/demo/MathGame.class
結(jié)果:redefine success, size: 1
測試:

2、war包的情況:
因為war包是直接放在tomcat啟動的,啟動arthas有點不一樣,我們先通過ps -ef|grep java命令查找tomcat中的java進(jìn)程pid

啟動arthas
[INFO] arthas-boot version: 3.3.3
[INFO] Process 6870 already using port 8563
[ERROR] Target process 2854 is not the process using port 8563, you will connect to an unexpected process.
[ERROR] 1. Try to restart arthas-boot, select process 6870, shutdown it first with running the 'stop' command.
[ERROR] 2. Or try to use different http port, for example: java -jar arthas-boot.jar --telnet-port 9998 --http-port 9999
執(zhí)行如下命令
java -jar /data/arthas-boot.jar --telnet-port 9998 --http-port 9999 2854

我們事先在服務(wù)器上部署了一個war包
jad操作和jar包一樣,但當(dāng)在操作mc命令時,可能會報錯
沒關(guān)系,可以利用開發(fā)工具比如idea,將我們要修改的java類直接在本地編譯成class文件再上傳到服務(wù)器,我這邊編譯完成后上傳到/data/下面

然后在執(zhí)行redefine命令
測試:
沒修改之前的打印內(nèi)容

熱更新代碼后的打印內(nèi)容

您的一鍵三連,是我更新的最大動力,謝謝
山水有相逢,來日皆可期,謝謝閱讀,我們再會
我手中的金箍棒,上能通天,下能探海