线上调试工具 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

版权声明:本文为ttzzyy原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ttzzyy/p/11414051.html