線上除錯工具 jvm-sandbox使用
阿新 • • 發佈:2019-08-26
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