0%

SpringBoot-JMH

尝试在spring test中使用基准测试。

演示代码

  • JMH 是一个用于在 JVM 上编写基准测试的 Java 工具库,它是作为 OpenJDK 项目的一部分开发的。

  • 在与spring test集成过程中,只需要成功加载spring即可。

Console

  • 当jmh先启动,在启动spring就正常使用了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# JMH version: 1.21
# VM version: JDK 1.8.0_275, OpenJDK 64-Bit Server VM, 25.275-b01
# VM invoker: /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/bin/java
# VM options: -server
# Warmup: 1 iterations, 10 s each
# Measurement: 1 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: cn.z201.jmh.AppApplicationTest.environment

# Run progress: 0.00% complete, ETA 00:00:20
# Fork: N/A, test runs in the host VM
# *** WARNING: Non-forked runs may silently omit JVM options, mess up profilers, disable compiler hints, etc. ***
# *** WARNING: Use non-forked runs only for debugging purposes, not for actual performance runs. ***
# Warmup Iteration 1:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.5)

[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [StartupInfoLogger.java : 55] Starting application using Java 1.8.0_275 on z201MacBook-Pro.local with PID 23242 (started by zengqingfeng in /Users/zengqingfeng/word/code-example/SpringBoot-JMH)
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [SpringApplication.java : 679] The following profiles are active: dev
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [Bootstrap.java : 68] UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [ServletContextImpl.java : 371] Initializing Spring embedded WebApplicationContext
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [ServletWebServerApplicationContext.java : 289] Root WebApplicationContext: initialization completed in 809 ms
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [ExecutorConfigurationSupport.java : 181] Initializing ExecutorService 'applicationTaskExecutor'
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [Undertow.java : 120] starting server: Undertow - 2.2.7.Final
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [Xnio.java : 95] XNIO version 3.8.0.Final
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [NioXnio.java : 59] XNIO NIO Implementation Version 3.8.0.Final
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [Version.java : 52] JBoss Threads version 3.1.0.Final
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [UndertowWebServer.java : 133] Undertow started on port(s) 9031 (http)
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [StartupInfoLogger.java : 61] Started application in 2.018 seconds (JVM running for 3.629)
[cn.z201.jmh.AppApplicationTest.environment-jmh-worker-1] [AppApplicationTest.java : 40] dev

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
@Slf4j
@State(Scope.Benchmark)
public class AppApplicationTest {

private final static Integer MEASUREMENT_ITERATIONS = 1;
private final static Integer WARMUP_ITERATIONS = 1;

// 初始化容器,通过getBean获取spring 管理的bean。
static ConfigurableApplicationContext context;

public String[] activeProfiles;

@Setup(Level.Trial)
public synchronized void initialize() {
try {
String args = "";
if (context == null) {
context = SpringApplication.run(AppApplication.class, args);
activeProfiles = context.getEnvironment().getActiveProfiles();
}
log.info("{}",activeProfiles);
} catch (Exception e) {
e.printStackTrace();
}
}

@Test
@Disabled
public void executeJmhRunner() throws RunnerException {
Options opt = new OptionsBuilder()
// 设置类名正则表达式基准为搜索当前类
.include("\\." + AppApplicationTest.class.getSimpleName() + "\\.")
// 都是一些基本的参数,可以根据具体情况调整。一般比较重的东西可以进行大量的测试,放到服务器上运行。
.warmupIterations(WARMUP_ITERATIONS) // 多少次预热
.measurementIterations(MEASUREMENT_ITERATIONS) // 要做多少次测量m
.timeUnit(TimeUnit.MILLISECONDS) // 毫秒
// 不使用多线程
.forks(0) // 进行 fork 的次数。如果 fork 数是2的话,则 JMH 会 fork 出两个进程来进行测试。
.threads(1) // 每个进程中的测试线程,这个非常好理解,根据具体情况选择,一般为cpu乘以2。
.mode(Mode.AverageTime)
.shouldDoGC(true)
.shouldFailOnError(true)
.resultFormat(ResultFormatType.JSON) // 输出格式化
// .result("/dev/null") // set this to a valid filename if you want reports
.result("benchmark.json")
.shouldFailOnError(true)
.jvmArgs("-server")
.build();
new Runner(opt).run();
}

@Benchmark
public void environment(){

}

}

END