天天看點

JVM-SandBox實踐Demo:修複一個損壞了的鐘

一、環境

linux環境(windows部分腳本不适配,會出現較多問題,建議在linux環境使用)

eclipse+JDK1.8+maven

二、下載下傳安裝jvm-sandbox

下載下傳位址:https://ompc.oss.aliyuncs.com/jvm-sandbox/release/sandbox-stable-bin.zip

在對應檔案夾下解壓:

unzip sandbox-stable-bin.zip

解壓後目錄如下:

JVM-SandBox實踐Demo:修複一個損壞了的鐘

目錄結構解析,參考文檔:https://github.com/alibaba/jvm-sandbox/wiki/CONFIG

三、定義一個損壞的時鐘

使用eclipse定義一個損壞的時鐘

package com.taobao.demo;

/**
 * 報時的鐘
 */
public class Clock {

    // 日期格式化
    private final java.text.SimpleDateFormat clockDateFormat
            = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 狀态檢查
     */
    final void checkState() {
        throw new IllegalStateException("STATE ERROR!");
    }

    /**
     * 擷取目前時間
     *
     * @return 目前時間
     */
    final java.util.Date now() {
        return new java.util.Date();
    }

    /**
     * 報告時間
     *
     * @return 報告時間
     */
    final String report() {
        checkState();
        return clockDateFormat.format(now());
    }

    /**
     * 循環播報時間
     */
    final void loopReport() throws InterruptedException {
        while (true) {
            try {
                System.out.println(report());
            } catch (Throwable cause) {
                cause.printStackTrace();
            }
            Thread.sleep(1000);
        }
    }

    public static void main(String... args) throws InterruptedException {
        new Clock().loopReport();
    }

}
           

java工程如下:

JVM-SandBox實踐Demo:修複一個損壞了的鐘

使用eclipse-export-Java-JAR file,打出jar包

JVM-SandBox實踐Demo:修複一個損壞了的鐘

注意點:

打出的jar包,在解壓包看到的META-INF目錄下的MANIFEST.MF,欠缺main-class檔案,導緻無法通過java -jar **.jar運作jar包,如圖所示:

JVM-SandBox實踐Demo:修複一個損壞了的鐘

是以在加壓目錄下加入内容:Main-Class: 類路徑 (注意:Main-Class: 與類路徑存在一個空格)

JVM-SandBox實踐Demo:修複一個損壞了的鐘

四、将打好的jar包,上傳到對應linux伺服器的目錄,運作程式

指令:java -jar Clock.jar

運作效果如下:

JVM-SandBox實踐Demo:修複一個損壞了的鐘

五、編寫一個子產品修複損壞的鐘

建立一個maven工程clock-tinker

maven依賴配置:

<parent>
    <groupId>com.alibaba.jvm.sandbox</groupId>
    <artifactId>sandbox-module-starter</artifactId>
    <version>1.2.0</version>
</parent> 
           

完整pom.xml檔案如下:

JVM-SandBox實踐Demo:修複一個損壞了的鐘
JVM-SandBox實踐Demo:修複一個損壞了的鐘
JVM-SandBox實踐Demo:修複一個損壞了的鐘

代碼如下:

package com.alibaba.jvm.sandbox.demo;

import com.alibaba.jvm.sandbox.api.Information;
import com.alibaba.jvm.sandbox.api.Module;
import com.alibaba.jvm.sandbox.api.ProcessController;
import com.alibaba.jvm.sandbox.api.annotation.Command;
import com.alibaba.jvm.sandbox.api.listener.ext.Advice;
import com.alibaba.jvm.sandbox.api.listener.ext.AdviceListener;
import com.alibaba.jvm.sandbox.api.listener.ext.EventWatchBuilder;
import com.alibaba.jvm.sandbox.api.resource.ModuleEventWatcher;
import org.kohsuke.MetaInfServices;

import javax.annotation.Resource;

@MetaInfServices(Module.class)
@Information(id = "broken-clock-tinker")
public class BrokenClockTinkerModule implements Module {

    @Resource
    private ModuleEventWatcher moduleEventWatcher;

    @Command("repairCheckState")
    public void repairCheckState() {

        new EventWatchBuilder(moduleEventWatcher)
                .onClass("com.taobao.demo.Clock")
                .onBehavior("checkState")
                .onWatch(new AdviceListener() {

                    /**
                     * 攔截{@code com.taobao.demo.Clock#checkState()}方法,當這個方法抛出異常時将會被
                     * AdviceListener#afterThrowing()所攔截
                     */
                    @Override
                    protected void afterThrowing(Advice advice) throws Throwable {
                        
                        // 在此,你可以通過ProcessController來改變原有方法的執行流程
                        // 這裡的代碼意義是:改變原方法抛出異常的行為,變更為立即傳回;void傳回值用null表示
                        ProcessController.returnImmediately(null);
                    }
                });

    }

}
           

目錄結構如下:

JVM-SandBox實踐Demo:修複一個損壞了的鐘

maven打包

對應工程-Run As-Run Configurations,在Goals 輸入指令:clean package

JVM-SandBox實踐Demo:修複一個損壞了的鐘

運作成功标志

JVM-SandBox實踐Demo:修複一個損壞了的鐘

六、将修複時鐘的maven jar包上傳到sandbox/sandbox-module目錄下

JVM-SandBox實踐Demo:修複一個損壞了的鐘

七、檢視Clock.jar運作的程序号

指令:jps -l

JVM-SandBox實踐Demo:修複一個損壞了的鐘

八、啟動沙箱

在sanbox目錄下的bin目錄,啟動沙箱,使用指令:

./sandbox.sh -p 17990

注意:17990是目标程序号

JVM-SandBox實踐Demo:修複一個損壞了的鐘

九、檢視修複程式挂載情況

./sandbox.sh -p 17990 -l

JVM-SandBox實踐Demo:修複一個損壞了的鐘

注意:如果沒有出現broken -clock-tinker的内容,說明挂載失敗,注意檢視日志報錯情況

可通過配置:cfg/sandbox-logback.xml設定sandbox的日志目錄:

JVM-SandBox實踐Demo:修複一個損壞了的鐘

個人修改位址如下:

JVM-SandBox實踐Demo:修複一個損壞了的鐘

對應目錄下有日志

JVM-SandBox實踐Demo:修複一個損壞了的鐘

十、修複clock#checkState()方法

執行指令:觸發BrokenClockTinkerModule#repairCheckState()方法執行

JVM-SandBox實踐Demo:修複一個損壞了的鐘

檢視修複效果

JVM-SandBox實踐Demo:修複一個損壞了的鐘

十一、解除安裝沙箱

指令:./sandbox.sh -p 目标程序号 -S

JVM-SandBox實踐Demo:修複一個損壞了的鐘

解除安裝沙箱後,故障繼續,目标程式運作結果

JVM-SandBox實踐Demo:修複一個損壞了的鐘

參考文檔:https://github.com/alibaba/jvm-sandbox/wiki/FIRST-MODULE