【Arthas】ホットアップデート

2770 ワード

ホットアップデートは何ですか?
Javaアプリケーションを停止しない場合は、仮想マシン内のバイトコードを直接置き換えます.
使い道?
比較的多いのはテスト環境debugです.テスト環境はローカル環境のようにデバッグが便利ではなく、コンパイル、パッケージング、導入が必要です.
手順
ここでは、Arthasを使用してホット・アップデートを実装する方法について説明します.
まず、テストに使用するjavaプログラムを見てみましょう.
/**
 * Hello world!
 *
 */
public class App 
{

    private double get(){
        return Math.random();
    }

    private void run(){
        for (int i = 0; i < 1000000000; i++) {
            try {
                Thread.sleep(5000);
                System.out.println(get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main( String[] args ) throws IOException {

        new App().run();
    }
}

mavenを使用して、直接実行できるjarパッケージを打ち出し、実行します.
1秒ごとに0~1の小数点を印刷すると、出力は次のように表示されます.
⇒  java -jar testMaven1-1.0-SNAPSHOT.jar 0.7839043482348526 0.11390699050234909 0.9107929624621809 0.9384221341175452
 
次に、ホットアップデートを開始します.
java -jar arthas-boot.jar

上のコマンドを使用してarthasを起動します.前のjavaプログラムプロセスを選択します.
miracle@localhost:~/arthas|⇒  java -jar arthas-boot.jar [INFO] arthas-boot version: 3.1.1 [INFO] Found existing java process, please choose one and hit RETURN. * [1]: 12683 org.jetbrains.idea.maven.server.RemoteMavenServer   [2]: 17166 testMaven1-1.0-SNAPSHOT.jar   [3]: 12655 2
1)jadコマンドを使用して逆コンパイル:
jad --source-only com.liyao.App > App.java

--source-onlyパラメータを追加する必要があります.そうしないと、ソースファイルにclassloaderの情報が添付され、直接コンパイルできません.
後は全限定クラス名です.
結果はデフォルトで端末出力なので、ファイルにリダイレクトします.
 
2)javaソースファイルの変更:
ここでvimを直接使用し,getメソッドの戻り値に100を加算する.
 27     private double get() {
 28         return 100 + Math.random();
 29     }

 
3)mcコマンドを使用して、新しいjavaファイルをコンパイルします.
mc App.java

$ mc App.java Memory compiler output:/Users/miracle/test/mvn/testMaven1/target/com/liyao/App.class Affect(row-cnt:1) cost in 463 ms.
 
4)redefineコマンドを使用してバイトコードファイルを再ロードします.
redefine /Users/miracle/test/mvn/testMaven1/target/com/liyao/App.class

redefine success, size: 1
 
次に、前のjavaアプリケーションの出力を見てみましょう.
0.1164675982131923 0.8292291692991027 0.5282152149562233 0.8430507304634605 0.7346896134684758 0.8252403266819852 0.059211801561579343100.38541391802795 100.883545978571243は、更新後の戻り値であることがわかります.
 
redefineコマンドの制限:
メンバー変数またはメソッドを新規または削除できません.
それ以外の場合は、次のエラーが発生します.
redefine error! java.lang.UnsupportedOperationException: class redefinition failed: attempted to add a method
redefine error! java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)