【Arthas】ホットアップデート
2770 ワード
ホットアップデートは何ですか?
Javaアプリケーションを停止しない場合は、仮想マシン内のバイトコードを直接置き換えます.
使い道?
比較的多いのはテスト環境debugです.テスト環境はローカル環境のようにデバッグが便利ではなく、コンパイル、パッケージング、導入が必要です.
手順
ここでは、Arthasを使用してホット・アップデートを実装する方法について説明します.
まず、テストに使用するjavaプログラムを見てみましょう.
mavenを使用して、直接実行できるjarパッケージを打ち出し、実行します.
1秒ごとに0~1の小数点を印刷すると、出力は次のように表示されます.
⇒ java -jar testMaven1-1.0-SNAPSHOT.jar 0.7839043482348526 0.11390699050234909 0.9107929624621809 0.9384221341175452
次に、ホットアップデートを開始します.
上のコマンドを使用して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コマンドを使用して逆コンパイル:
--source-onlyパラメータを追加する必要があります.そうしないと、ソースファイルにclassloaderの情報が添付され、直接コンパイルできません.
後は全限定クラス名です.
結果はデフォルトで端末出力なので、ファイルにリダイレクトします.
2)javaソースファイルの変更:
ここでvimを直接使用し,getメソッドの戻り値に100を加算する.
3)mcコマンドを使用して、新しい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 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)
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)