Arthas實踐--jad/mc/redefine線上熱更新


Arthas是Alibaba開源的Java診斷工具,功能很強大。官方中文文檔:https://alibaba.github.io/arthas/index.html

本篇主要是介紹 jad / mc / redefine 這三個命令的配合使用,以達到熱更新代碼的目的(命令的詳細使用可參考https://alibaba.github.io/arthas/commands.html)。

 

1、上傳MathGame.java文件(官網的例子)到linux服務器:

import java.util.concurrent.TimeUnit;

/**
 * 用於Arthas測試jad/mc/redefine命令
 */
public class MathGame {

    public static void main(String[] args) throws InterruptedException {
        MathGame game = new MathGame();
        while (true) {
            game.run();
            TimeUnit.SECONDS.sleep(1);

            // 這個不生效,因為代碼一直跑在 while里
            System.out.println("in loop");
        }
    }

    public void run() throws InterruptedException {
        // 這個生效,因為run()函數每次都可以完整結束
        System.out.println("call run()");
    }

}

 

2、編譯java文件並啟動:

 

 3、使用命令java -jar arthas-boot.jar,啟動Arthas服務:

 

 4、jad命令反編譯MathGame,並將結果輸出到 /tmp/MathGame.java

jad --source-only MathGame > /tmp/MathGame.java

 --source-only選項,可以只打印源代碼。

該命令其實很實用,可以查看線上運行的代碼是不是自己想要部署的代碼

 

5、修改 /tmp的MathGame.java文件,把打印信息加一個"---new"

 

 6、mc內存編譯代碼。將保存好的MathGame.java文件編譯成class文件(也可以在本地使用javac命令編碼):

mc /tmp/MathGame.java -d /tmp

 

7、redefine重新加載編譯好的.class文件:

redefine /tmp/MathGame.class

可以看到打印結果變了:

redefine的限制:

  • 不允許新增field、method
  • 正在跑的函數,沒有退出不能生效。比如上面主函數里的System.out.println("in loop"),只有 run 函數里的才會生效

 

推薦使用 retransform,具體原因可參考:https://arthas.aliyun.com/doc/redefine.html 

在使用的過程中發現了一個疑問:當執行完redefine后,最新代碼也生效了,但如果此時再次執行 jad 方法,會發現代碼變成之前的代碼了,並且JVM運行的也是之前的

如果有知道的人,可以在下方評論區回答下,小弟不勝感激~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM