1. 程式人生 > >線上除錯工具 jvm-sandbox使用

線上除錯工具 jvm-sandbox使用

jvm-sandbox使用

1 快速安裝

  • 1.1 下載解壓

    # 下載最新版本的JVM-SANDBOX
    wget http://ompc.oss-cn-hangzhou.aliyuncs.com/jvm-sandbox/release/sandbox-stable-bin.zip
    
    # 解壓
    unzip sandbox-stable-bin.zip
  • 1.2 掛載目標應用

    # 進入沙箱執行指令碼
    cd sandbox/bin
    
    # 常用命令!!!
    # 目標JVM程序73366(假設,使用jps命令檢視)
    ./sandbox.sh -p 73366
    #解除安裝沙箱
    ./sandbox.sh -p 73366 -S
    #查詢沙箱
    ./sandbox.sh -p 73366 -l
    #重新整理沙箱
    ./sandbox.sh -p 73366 -F
    #使用自定義module執行(my-sandbox-module:自定義的module名字,addLog自定義切入方法名字)
    ./sandbox.sh -p 73366 -d 'my-sandbox-module/addLog'
    
    #日誌配置及檢視
    #配置檔案在    /sandbox/cfg/sandbox-logback.xml
    #預設日誌路徑    ~/logs/sandbox/sandbox.log

2 快速使用demo

本例採用maven多工程模式:(注意自己的父子結構引用)

  • 主pom.xml(參考)

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <dependencies>
            <!--springboot start-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
    
                <!-- 去除對預設日誌的依賴 -->
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-logging</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <!--junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <scope>test</scope>
            </dependency>
            <!--log start-->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
            </dependency>
            <!--springAop-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
            <!--log end-->
            <!--springboot end-->
    
        </dependencies>
  • springboot-sandbox工程pom.xml

        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
  • module-sandbox工程pom.xml

        <dependencies>
            <dependency>
                <groupId>com.alibaba.jvm.sandbox</groupId>
                <artifactId>sandbox-api</artifactId>
                <version>1.2.0</version>
            </dependency>
            <dependency>
                <groupId>org.kohsuke.metainf-services</groupId>
                <artifactId>metainf-services</artifactId>
                <version>1.7</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <configuration>
                        <archive>
                            <manifest>
                                <!-- <mainClass>com.sandbox.test.MySandBoxModule</mainClass>-->
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id> <!-- 此處指定繼承合併 -->
                            <phase>package</phase> <!-- 繫結到打包階段 -->
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
    
            </plugins>
        </build>

2.1 springboot-sandbox程式碼

  • 啟動類SandboxApp

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class SandboxApp {
        public static void main(String[] args) {
            SpringApplication.run(SandboxApp.class, args);
        }
    }
    
  • 需要被掛載切入方法的類TestSandbox

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.ApplicationArguments;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.stereotype.Component;
    
    import java.util.concurrent.atomic.LongAdder;
    
    
    @Slf4j
    @Component
    public class TestSandbox implements ApplicationRunner {
    
        private final LongAdder longAdder = new LongAdder();
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            while (true) {
                longAdder.add(1);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                test(longAdder);
            }
        }
    
        private void test(LongAdder longAdder) {
            log.info("TestSandBox------->" + longAdder);
        }
    
    }
  • 打包上傳伺服器使用java -jar 啟動

2.2 module-sandbox程式碼

  • 切入方法類MySandBoxModule

    import com.alibaba.jvm.sandbox.api.Information;
    import com.alibaba.jvm.sandbox.api.Module;
    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 lombok.extern.slf4j.Slf4j;
    import org.kohsuke.MetaInfServices;
    
    import javax.annotation.Resource;
    
    @MetaInfServices(Module.class)
    @Information(id = "my-sandbox-module")// 模組名,在指定掛載程序後通過-d指定模組,配合@Command註解來唯一確定方法
    @Slf4j
    public class MySandBoxModule implements Module {
    
        @Resource
        private ModuleEventWatcher moduleEventWatcher;
    
        @Command("addLog")// 模組命令名
        public void addLog() {
            new EventWatchBuilder(moduleEventWatcher)
                    .onClass("com.sandbox.test.TestSandbox")// 想要對 TestSandbox 這個類進行切面
                    .onBehavior("test")// 想要對上面類的 bathSave 方法進行切面
                    .onWatch(new AdviceListener() {
                        //對方法執行之前執行
                        @Override
                        protected void before(Advice advice) throws Throwable {
                            log.info("sandbox切入成功!!!!!!");
                            //獲取方法的所有引數
                            Object[] parameterArray = advice.getParameterArray();
                            if (parameterArray != null) {
                                for (Object po : parameterArray) {
                                    log.info("形參型別為:" + po.getClass().getName() + "!!!!!!!");
                                    log.info("形參值為:" + po + "!!!!!!!");
                                }
                            }
                        }
                    });
        }
    }
  • 使用 mvn clean compile assembly:single打包,上傳至sandbox/sandbox-module目錄下

2.3 使用命令掛載使用

參考: https://github.com/alibaba/jvm-sandbox

參考專案: https://github.com/70416450/jvm-sandbox