4年前 (2021-04-28)  相关技术 |   抢沙发  2968 
文章评分 0 次,平均分 0.0

GraalVM原生镜像性能测试:Spring VS Quarkus

GraalVM是一个通用的虚拟机,用于运行应用程序,如JavaScript、Python、Ruby、R、JVM等语言,如java、Scala、Groovy、Kotlin、Crojule和基于LLVM的语言,如C++和C++。

对我来说,最有趣的特性之一是编译为基于JVM的应用程序的本机二进制(在GraalVM中通常称为本机映像)。本机映像意味着编译将是独立的,不需要JVM(如C、C++或Golang),但它具有权衡(JIT vs AOT)和限制。

Spring框架,JVM世界中最成熟和最流行的框架之一,2019年中,SpringGraalVM特性被开发用于支持SpringBoot的本机映像编译(SpringFramework 5.2),但它需要巨大的内存构建过程,这个提交使得内存使用量更小。

一些新的Java框架已经具备了现成的本机图像编译功能,比如Quarkus、Micronaut和Helidon。几个月前我有兴趣尝试Quarkus,实际上1.0是去年11月发布的,但是我没有太多的空闲时间来尝试。几个月前,在尝试了几天的Quarkus之后,我很好奇用Spring(SpingGraal native)对Quarkus进行基准测试。

几周前,SpringGraalNative0.7.1已经发布,很多问题已经解决,我在GCP上有免费的学分,所以,让我们再试一次,做一些基准测试。我知道现在比较springgraalvm native是不公平的,也许我们可以说这是一个“实验报告”。

应用

该基准测试针对四种类型的应用程序

  • 带WebMVC的SpringBoot
  • 带Webflux的
  • SpringBoot
  • Quarkus
  • 带Spring API扩展的Quarkus

所有这些都只是简单的CRUD应用程序通过http和PostgreSQL数据库。有6个http端点

  • 插入
  • 按id查找
  • 按页查找
  • 按特定列查找(筛选)
  • 更新
  • 删除。

Webflux版本中的Spring数据和JDBC版本不是被动的。我添加Webflux版本只是为了比较,因为Quarkus是基于Netty的。

有关如何将应用程序编译为本机映像,您可以查看Quarkus的此文档和spring graalvm本机的此文档。我对springgraalvm本机和自定义构建脚本使用混合模式。

对于框架和运行时版本,我使用springboot2.3.1(springgraalvm native 0.7.1)、quarkus1.5.2、graalvm2.1.0java11。

构建过程

构建过程是在4个CPU、16 GiB RAM虚拟机上完成的,空闲时RAM使用率为2.8%。

1. 构建时间

  • spring-boot8分39秒
  • spring-boot-webflux 8分12秒
  • quarkus3分55秒
  • quarkus spring api 3分57秒

GraalVM原生镜像性能测试:Spring VS Quarkus

在我多次尝试编译之后,构建时间的不一致性可能会达到20-30秒。

2. CPU使用率(%)随时间变化

GraalVM原生镜像性能测试:Spring VS Quarkus

3. 内存使用率(%)

GraalVM原生镜像性能测试:Spring VS Quarkus

4. 峰值RAM使用率

  • spring-boot10.1 GiB
  • spring-bootwebflux 9.8 GiB
  • quarkus8 GiB
  • quarkus spring api 8 GiB

5. 二进制大小

  • spring-boot196.6 MB
  • spring-boot webflux 182.7 MB
  • quarkus69.8 MB
  • quarkus spring api 69.6 MB

好吧,Spring的构建时间和二进制大小的结果要高得多,让我们等待spring5.3和springgraalvm native的非实验版本。

启动时间

所有的应用程序都是在1s下在2个CPU或1个CPU上启动的。

压力测试

虚拟机规范化

数据库:6 VCPU,16 GiB RAM,SSD(us-west1-b)

应用:1 VCPU,2 GiB RAM(us-west1-b)

JMeter:4 VCPU,16 GiB RAM(us-west2-a)

JMeter VM位于不同的区域,因为我使用了免费试用帐户,每个区域有8个vcpu限制。

脚本

我使用JMeter随机控制器随机请求所有端点15分钟。在此之前,我截断表并插入10000条记录。

我没有对所有的应用程序做特别的调整或其他什么,所有的默认值(包括springwebmvc,所以,200个tomcat线程),只是设置了连接池的数量。我只在VM级别做了一些调整,增加了打开文件的最大数量,并启用了tcp_tw_reuse

吞吐量结果

在运行15分钟测试之前,我尝试了几个60秒的测试,以找到这种VM规范最合适的设置(JMeter线程(并发用户)和连接池数量)。我使用Quarkus作为基线,这是结果。

GraalVM原生镜像性能测试:Spring VS Quarkus

基于这个结果,我认为150个JMeter线程足够大了。为了提高效率,让我们只使用池中的2个连接和1vCPU。

这是池中2个连接在15分钟内处理150jmeter线程的结果。

  • spring-boot 390.1/s
  • spring-boot webflux 631.6/s
  • quarkus 1042.7/s
  • quarkus spring api 871.1/s

这是一段时间内(每30秒)的平均吞吐量。

GraalVM原生镜像性能测试:Spring VS Quarkus

资源利用(压力测试期间)

应用程序虚拟机

CPU使用率(%)随时间变化

注意:quarkus spring api和所有spring版本的应用程序VM CPU使用率随着时间的推移而减少。但在dbvm上,该版本的CPU使用率正在增加。

随时间推移的RAM使用率(%)

数据库虚拟机

CPU使用率(%)随时间变化

GraalVM原生镜像性能测试:Spring VS Quarkus

注意:quarkus spring api和所有spring版本的数据库VM CPU使用率随着时间的推移而增加。我还没有进一步调查。可能是因为我在查找JMeter线程数时使用了Quarkus版本作为基线,而另一个无法使用该设置处理请求。

CPU使用率(%)随时间变化

GraalVM原生镜像性能测试:Spring VS Quarkus

完整代码地址:https://github.com/ard333/native-binaries-benchmark

 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/1868.html

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册