我有一个使用spring boot
框架开发的应用程序,想要利用JMH
进行性能测试。如果有任何关于这个集成的参考资料,那将非常有帮助。
我有一个使用spring boot
框架开发的应用程序,想要利用JMH
进行性能测试。如果有任何关于这个集成的参考资料,那将非常有帮助。
解决方案比我想象的要简单。重要的是在基准测试初始化时启动spring-boot应用程序。为配置上下文定义一个类级变量,并在基准测试的设置期间给它一个引用。在基准测试中调用bean方法。
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
@BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.MINUTES)
@State(Scope.Thread)
public class ProcessFeedBenchMark {
public static void main(String args[]) throws Exception {
URLClassLoader classLoader = (URLClassLoader) ProcessFeedBenchMark.class.getClassLoader();
StringBuilder classpath = new StringBuilder();
for(URL url : classLoader.getURLs())
classpath.append(url.getPath()).append(File.pathSeparator);
classpath.append("/D:/work/zymespace/benchmark/src/main/resources/").append(File.pathSeparator);
System.out.print(classpath.toString());
System.setProperty("java.class.path", classpath.toString());
Options opt = new OptionsBuilder()
.include(ProcessFeedBenchMark.class.getName() + ".*")
.timeUnit(TimeUnit.MILLISECONDS)
.threads(1)
.shouldFailOnError(true)
.shouldDoGC(true)
.build();
new Runner(opt).run();
}
static ConfigurableApplicationContext context;
private BenchmarkTestService service;
@Setup (Level.Trial)
public synchronized void initialize() {
try {
String args = "";
if(context == null) {
context = SpringApplication.run(BenchmarkSpringBootStater.class, args );
}
service = context.getBean(BenchmarkTestService.class);
System.out.println(service);
} catch(Exception e) {
e.printStackTrace();
}
}
@Benchmark
public void benchmark1 (ProcessFeedBenchMark state, Blackhole bh) {
try {
service.li();
} catch (Exception e) {
e.printStackTrace();
}
}
}
不需要启动Spring上下文来对一个方法进行基准测试。实际上,我不确定你真正想要在这里基准测试什么,因为方法的实现并没有改变。如果你只是想计时该方法,直接调用该方法会更简单、更可靠。如果你想基准测试在不同情况下的启动时间,请参见我的答案here。
jmh
不适用于基准测试应用程序,而只适用于特定方法。 - Slava Semushin