在阿 B 上看到某个大 V 做的对比 spring 和 quarkus 的视频
Java 抗 Go 急先锋!? Quarkus 很优秀,但我不会碰它!
由于怀疑他引用文章的测试方式, 这两天简单的测试了一下两者性能差别.
技术栈分别是
- spring-boot + webmvc + kotlin + gradle(kotlin)
- spring-boot + webflux + kotlin + gradle(kotlin)
- quarkus + resteasy + kotlin + gradle(kotlin)
- quarkus + resteasy-reactive + kotlin + gradle(kotlin)
响应内容
HTTP/1.1 200 OK
Content-Length: 5
Content-Type: text/plain;charset=UTF-8
Hello
测试代码
classic 直接返回 Hello
reactive 返回 Uni.createFrom().item("Hello") 和 Mono.just("Hello")
测试环境
cpu i5 10400
内存 ddr4 2666mhz 16G*2
测试命令
wrk -t 10 -c50 -d60s http://localhost:8080/hello
结果
JVM 测试
| 测试内容 | spring-classic | spring-reactive | quarkus-classic | quarkus-reactive |
|---|---|---|---|---|
| 文件大小 | 22M | 26M | 19M | 19M |
| 构建时间 | 14s | 9s | 9s | 4s |
| 启动时间 | 2.175s | 2.11s | 0.648s | 0.583s |
| requests per second | 125271.73 | 148780.37 | 185037.19 | 356713.09 |
| requests per second (-Xmx32m) | OOM | 58833.49 | 165686.72 | 221624.35 |
| requests per second (-Xmx128m) | 108679.42 | 149184.19 | 199035.62 | 364742.43 |
| 内存占用 | 876m | 800m | 472m | 461m |
| 内存占用 (-Xmx32m) | OOM | 218m | 196m | 174m |
| 内存占用 (-Xmx128m) | 291m | 345m | 255m | 203m |
native 测试
| 测试内容 | spring-classic | spring-reactive | quarkus-classic | quarkus-reactive |
|---|---|---|---|---|
| 文件大小 | 75M | 74M | 41M | 49M |
| 构建时间 | 1m 31s | 1m 37s | 48s | 53s |
| 启动时间 | 0.013s | 0.029s | 0.010s | 0.011s |
| requests per second | 73348.17 | 73843.59 | 103080.93 | 173766.21 |
| requests per second (-Xmx32m) | 331.39 | 1974.81 | 1040.43 | 78649.30 |
| requests per second (-Xmx128m) | 38277.29 | 62579.76 | 7283.71 | 174645.15 |
| 内存占用 | 326m | 147m | 411m | 330m |
| 内存占用 (-Xmx32m) | 110m | 84m | 43m | 39m |
| 内存占用 (-Xmx128m) | 108m | 102m | 54m | 58m |
docker 镜像 (1 cpu)
| 测试内容 | spring-reactive | quarkus-reactive |
|---|---|---|
| 镜像大小 | 106MB | 80.5MB |
| 内存占用 (-m 32m) | 报错退出 | 7.758MiB / 32MiB |
| requests per second (-m 32m) | 报错退出 | 28273.76 |
| 内存占用 (-m 64m) | 报错退出 | 12.85MiB / 64MiB |
| requests per second (-m 64m) | 报错退出 | 29490.30 |
| 内存占用 (-m 128m) | 41.89MiB / 128MiB | 19.11MiB / 128MiB |
| requests per second (-m 128m) | 2292.46 | 29396.50 |
| 内存占用 (-m 256m) | 48.02MiB / 256MiB | 32.28MiB / 256MiB |
| requests per second (-m 256m) | 2250.47 | 29820.38 |
小结
- jvm 模式下, spring-reactive 对比阻塞式提升约 0.2-0.4 倍,quarkus-reactive 对比阻塞式提升约 1 倍
- native 模式下, 各种应用性能都下降 50%左右
- jvm 模式下堆内存设置为 32m 时, spring mvc oom, 其他应用正常运行
- native 模式下堆内存设置为 32m 时, 除 quarkus-reactive 外, 其他应用性能糟糕
- native 模式下堆内存设置为 128m 时, quarkus-classic 性能明显较其他应用糟糕
- docker 容器运行时, spring 应用最小需要分配 128m 内存, quarkus 只需要 8m, 此时 rps 为 7189.86
- docker 容器运行时, 单 cpu 情况下,spring-reactive 性能糟糕, rps 仅为 2300 左右
- native 应用启动都很快, jvm 模式下,quarkus 比 spring 启动时间少 3/4
- spring native 构建时间约为 quarkus 2 倍, 但是都很慢