0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Quarkus是SpringBoot的替代品吗?

jf_ro2CN3Fa 来源:稀土掘金 2023-11-10 10:01 次阅读

1 概述

SpringBoot框架不用多介绍,Java程序员想必都知道。相对来说熟悉Quarkus的人可能会少一些。Quarkus首页放出的标语:超音速亚原子的Java(Supersonic Subatomic Java)。

它是为 OpenJDK HotSpot 和 GraalVM 量身定制的 Kubernetes Native Java 框架,基于同类最佳的 Java 库和标准制作而成。Quarkus 的到来为开发 Linux 容器和 kubernetes 原生 Java 微服务带来了一个创新平台。

在本文中,我们将对这两个 Java 框架 Spring Boot 和 Quarkus 进行简单的比较。我们可以更好地了解它们之间的异同,以及一些特殊性。我们还会执行一些测试来衡量它们的性能。最后,我们会介绍一个开发人员如何从Spring转换到Quarkus。

2 SpringBoot

Spring Boot 是一个基于 Java 的框架,专注于企业应用。它可以简单使用所有 Spring 项目,并集成了许多开箱即用的功能,来帮助开发人员提高生产力。

Spring Boot减少了配置和样板代码的数量。此外,由于其约定优于配置 方法,它根据依赖项自动注册默认配置,大大缩短了 Java 应用程序的开发周期。

3 Quarkus

Quarkus 是另一个采用与上述 Spring Boot 类似方法的框架,但还有一个额外的优点,即以更快的启动时间、更好的资源利用率和效率交付更小的工件 (Supersonic、Subatomic)。

它针对云、无服务器和容器化环境进行了优化。尽管侧重点略有不同, Quarkus 也能与最流行的 Java 框架很好地集成。

4 比较

如上所述,这两个框架都与其他项目和框架有很好的集成。但是,它们的内部实现和架构是不同的。例如,Spring Boot 提供两种类型的 Web 功能:阻塞(Servlets)和非阻塞(WebFlux)

另一方面,Quarkus 也提供这两种方法,但与 Spring Boot 不同的是,它允许我们同时使用 阻塞和非阻塞方法。此外,Quarkus 在其架构中嵌入了反应式 编程方法。

为了在我们的比较中获得更准确的数据,我们将使用两个完全响应式的应用程序,这些应用程序使用 Spring WebFlux 和 Quarkus 响应式功能实现。

此外,Quarkus 项目中最重要的功能之一是能够创建原生镜像(Native Images,基于特定平台的可执行二进制文件)。因此,我们还将在比较中包含两个原生映像,但 Spring 的原生镜像支持仍处于试验阶段。另外我们需要用到 GraalVM。

测试应用

我们的应用程序将实现三个 API:一个允许用户创建邮政编码,另一个用于查找特定邮政编码的信息,最后按城市查询邮政编码。这些 API 是使用了前面提到的 Spring Boot 和 Quarkus 的反应式方法实现的,数据库使用的是PostgreSQL。

我们的目标是创建一个比 HelloWorld 程序稍微复杂一些的样例程序。当然,数据库驱动和序列化框架等内容的实现会影响我们的比较结果。但是,大多数应用程序可能都会需要处理这些事情。

因此,比较的目的并不是为了证明哪个框架更好或更高效,而是分析研究这些特定实现的一个案例。

测试计划

为了测试这两种实现,我们将使用 JMeter 执行测试,并分析其测试报告。此外,我们将使用 VisualVM 在执行测试期间监控应用程序的资源利用率。

测试将运行 5 分钟,会调用所有 API,从预热期开始,然后增加并发用户数,直到达到 1,500。我们将在前几秒钟开始填充数据库,然后开始查询,如下所示:

96ae35ac-7f69-11ee-939d-92fbcf53809c.jpg96ba23f8-7f69-11ee-939d-92fbcf53809c.jpg

所有测试均在以下规格的机器上进行:

96c6277a-7f69-11ee-939d-92fbcf53809c.jpg

由于缺乏与其他后台进程的隔离,最终结果可能不太理想,但正如前面提到的,我们无意对这两个框架的性能进行广泛而详细的分析。

5 调查结果

对开发人员来说,这两个项目的体验都很棒,但值得一提的是 Spring Boot 有更好的文档,在网上也可以找到更多资料。Quarkus 在这方面正在改进,但仍然有点落后。

在指标方面,我们有如下结果:

96d1758a-7f69-11ee-939d-92fbcf53809c.jpg

通过这个实验,我们可以观察到 Quarkus 在 JVM 和原生版本的启动时间方面几乎比 Spring Boot 快一倍 。构建时间也快得多。在原生镜像的情况下,构建耗时:9 分钟(Quarkus)对 13 分钟(Spring Boot),JVM 构建耗时:20 秒(Quarkus)对 39 秒(Spring Boot)。

Artifact(工件)的大小出现了同样的情况,Quarkus 生成了更小的工件而再次领先。原生映像:75MB (Quarkus) 对 109MB (Spring Boot),以及JVM 版本:4KB (Quarkus) 对 26MB (Spring Boot)。

关于其他指标,结论并不是那么显而易见。因此,我们需要更深入地了解一下。

CPU

我们看到 JVM 版本在预热阶段开始时消耗更多的 CPU 。之后CPU使用率趋于稳定,所有版本的消耗相对均等。

以下是 JVM 和 Native 版本中 Quarkus 的 CPU 消耗:

96db357a-7f69-11ee-939d-92fbcf53809c.jpg

JVM 版的 Quarkus

96ee95d4-7f69-11ee-939d-92fbcf53809c.jpg

Native 版的 Quarkus

内存

内存就更复杂了。首先,很明显,两个框架的 JVM 版本都为Heap(堆)预留了更多内存 。尽管如此,Quarkus 从一开始就预留了较少的内存 ,启动期间的内存利用率也是如此。

然后,查看测试期间的利用率,我们可以观察到Native版本似乎不像 JVM 版本那样有效或频繁地回收内存。可以通过调整一些参数来改善这一点,在这个比较中,我们使用了默认参数,并没有对 GC、JVM 选项或任何其他参数进行更改。

让我们看一下内存使用图:

96f2c2c6-7f69-11ee-939d-92fbcf53809c.jpg

Spring Boot JVM

970066b0-7f69-11ee-939d-92fbcf53809c.jpg

Quarkus JVM

970ab372-7f69-11ee-939d-92fbcf53809c.jpg

Spring Boot 原生

971b516e-7f69-11ee-939d-92fbcf53809c.jpg

Quarkus 原生

在测试期间尽管Quarkus出现了更高的峰值,但确实消耗的内存资源更少。

响应时间

最后,关于响应时间和峰值使用的线程数,Spring Boot 似乎略微具有优势 。它能够使用更少的线程处理相同的负载,同时还具有更好的响应时间。

Spring Boot Native 版本在这种情况下表现出更好的性能。但是让我们看看每个版本的响应时间分布:

97283276-7f69-11ee-939d-92fbcf53809c.jpg

Spring Boot JVM

尽管有更多异常值,但 Spring Boot JVM 版本随着时间的推移取得了最好的进展,这很可能是由于 JIT 编译器优化 [1]。

9732ce34-7f69-11ee-939d-92fbcf53809c.jpg

Quarkus JVM

97482c48-7f69-11ee-939d-92fbcf53809c.jpg

Spring Boot 原生

9754a6ee-7f69-11ee-939d-92fbcf53809c.jpg

Quarkus 原生

Quarkus 在低资源利用率方面表现出强大的实力。然而,至少在这个实验中,Spring Boot 在吞吐量和响应能力方面与Quarkus旗鼓相当。

这两个框架都能够处理所有请求而没有任何错误。不仅如此,他们的表现也十分相似,并没有太大的差距。

总而言之

考虑到所有因素,在实现 Java 应用程序时,这两个框架都是很好的选择。

Native程序速度快且资源消耗低,是无服务器、短期(short-living)应用和资源消耗敏感环境的绝佳选择。

另一方面,JVM 应用程序似乎有更多的开销,但随着时间的推移具有出色的稳定性和高吞吐量,非常适合健壮、长寿命的应用程序。

测试程序的代码和用于测试它们的脚本可以在 GitHub 上找到 [2]。

6 从 Spring 转换到 Quarkus

随着K8s的兴起,对原生应用支持良好的Quarkus框架也越来越受到关注很多开发人员在考虑从 Spring 转换到 Quarkus。然而,开发人员在开始评估新的框架时通常必须搁置他们现有的知识。

幸运的是, Quarkus 不一样,因为它是由一群在 Java 技术方面具有深厚专业知识的工程师创建的。这包括 Spring API 兼容性,创建Quarkus的工程师同时也是在 Red Hat Runtime 上为 Spring Boot 提供支持的工程师。

7 我是 Spring 开发者,为什么要选Quarkus?

越来越明显的是,容器化,尤其是 Kubernetes,正在迫使人们重新评估 Java ,用于开发云原生应用程序。Kubernetes 是一种高度动态的共享基础设施。由于集群中托管的应用程序数量的增长以及对应用程序生命周期变化的响应能力的提高(例如重新部署和向上/向下扩展),基础设施的投入变得更加划算。

传统的 Java 云原生运行时在现有的栈上增加了新的分层,而没有真正重新考虑底层。这导致更大的内存消耗和更慢的启动时间,以至于现在很多公司为了从 Kubernetes 集群的大量投资中获得更多价值,愿意放弃他们深厚的 Java 专业知识,为 Go 和 Node.js 重新培养人才和开发工具。

9761ecdc-7f69-11ee-939d-92fbcf53809c.jpg

传统云原生 Java 栈

这正是 Quarkus 解决的问题。Quarkus 针对内存使用率和快速启动时间进行了优化。与其他云原生 Java 栈相比,在 JVM 上运行的 Quarkus 应用可以在相同数量的RAM中提供近两倍的应用程序实例,并且当打包为原生二进制文件时,实例数量增加了 7 倍。

这不仅仅是使用 SubstrateVM [3](GraalVM 的一个特性)简单地编译为原生二进制文件。

Quarkus 专为 Kubernetes 的基础设施优化了传统的 “高度动态”框架 ,从而降低了内存利用率并加快了初始启动速度,结果是运行时效率的显着提高。这些经过优化且文档齐全的框架称为“扩展 ”,由同类最佳的标准 API 组成。

976d0662-7f69-11ee-939d-92fbcf53809c.jpg

运行时效率

977a3b52-7f69-11ee-939d-92fbcf53809c.jpg

Quarkus 栈

我司为什么要从 Spring Boot 迁移到 Quarkus?

以我们公司为例,我司的旧系统基于 Spring 和 Tomcat。当我们维护和部署时,这个传统的框架给我们带来了一些困扰,基于以下原因我们决定迁移到Quarkus:

内存和 CPU 消耗:对于正在执行的操作,Spring 和 Tomcat 框架在应用的主要目的之外使用了过多的资源。

预热时间:Spring 应用程序可能需要 10-20 秒的时间才能启动,之后应用程序才可以开始预热。

无用的代码:作为开发人员,我们都讨厌样板代码(boilerplate code)。

测试:Quarkus 让编写单元测试和集成测试变得非常容易。只需在那里打一个@QuarkusTest 注释,它实际上会启动整个应用程序以运行您的测试。

横向扩展(Scale-out) vs. 纵向扩展(Scale-up):每个应用程序越小(资源方面),我们可以添加的越多。在这里横向可扩展性胜出。

学习曲线:Quarkus 的在线文档非常简单易懂。

8 Spring 开发者可以活用哪些现有知识?

Quarkus 的 Spring API 兼容性包括 Spring DI、Spring Web 和 Spring Data JPA。同时也在计划其他 Spring API,如 Spring Security 和 Spring Config。在 JVM 上运行时,Quarkus 应用程序几乎可以利用任何 Java 库。只要不使用 Java 反射 ,这些Java库就可以编译为原生。

例如,受 Spring 开发人员欢迎的 Lombok 库就可以原生编译。需要明确的是,Quarkus 中的 Spring API 兼容性并非为了作为一个完整的 Spring 平台来重新托管现有的 Spring 应用程序。目的是为了让基于 Quarkus 开发新应用程序成为一种自然的入门体验。结合预先优化的扩展 ,Quarkus 为微服务开发提供了大量的功能。很多开发人员已成功将 Spring 应用程序迁移到 Quarkus。

Spring 框架本质上是高度动态的。为了解决这个问题,Quarkus的Spring 兼容性扩展将 Spring API 映射到现有扩展中的 API,这些扩展已经针对快速启动、降低内存利用率和原生编译进行了优化,例如 RestEasy 和 CDI。此外,Quarkus的Spring 兼容性扩展不使用 Spring 应用程序上下文。由于这些原因,尝试使用额外的 Spring 库可能不会奏效。

Quarkus Spring Web Example

importjava.util.List;
importjava.util.Optional;
importorg.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/person")
publicclassPersonController{
@GetMapping(path="/greet/{id}",produces="text/plain")
publicStringgreetPerson(@PathVariable(name="id")longid){
Stringname="";
//...
returnname;
}

@GetMapping(produces="application/json")
publicIterablefindAll(){
returnpersonRepository.findAll();
}

Quarkus Spring Repository Example

packageorg.acme.springmp;

importjava.util.List;
importorg.springframework.data.repository.CrudRepository;

publicinterfacePersonRepositoryextendsCrudRepository{
ListfindByAge(intage);
}

Quarkus Spring Service + MicroProfile Fault Tolerance Example

importorg.eclipse.microprofile.faulttolerance.Fallback;
importorg.eclipse.microprofile.faulttolerance.Timeout;
importorg.eclipse.microprofile.rest.client.inject.RestClient;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.beans.factory.annotation.Value;
importorg.springframework.stereotype.Service;

@Service//Spring
publicclassPersonService{

@Autowired//Spring
@RestClient//MicroProfile
SalutationMicroProfileRestClientsalutationRestClient;

@Value("${fallbackSalutation}")//Spring
StringfallbackSalutation;

@CircuitBreaker(delay=5000,failureRatio=.5)//MicroProfile
@Fallback(fallbackMethod="salutationFallback")//MicroProfile
publicStringgetSalutation(){
returnsalutationRestClient.getSalutation();
}

9 对Spring开发者有额外的好处吗?

除了提高内存利用率和启动时间外,Quarkus 还为 Spring 开发人员提供了以下好处:

功能即服务 (FaaS) 。当编译为原生二进制文件时,Quarkus 应用程序可以在 0.0015 秒内启动,从而可以将现有的 Spring 和 Java API 知识与 FaaS 功能结合使用。(Azure、AWS Lambda)

实时编码 。从“Hello World”示例应用程序开始,然后将其转换为复杂的微服务,而无需重新启动应用程序。只需保存并重新加载浏览器即可查看沿途的变化。Quarkus 实时编码“开箱即用”,与 IDE 无关。

支持反应式和命令式模型。 Quarkus 有一个反应式核心,支持传统的命令式模型、反应式模型,或在同一应用程序中同时支持两者。

早期检测依赖注入错误。 Quarkus 在编译期间而不是在运行时捕获依赖项注入错误。

最佳框架和标准的结合 。Quarkus 在同一应用程序中支持 Spring API 兼容性、Eclipse Vert.x、MicroProfile(JAX-RS、CDI 等)、反应式流和消息传递等,可以在一个项目中同时使用 Spring 和 MicroProfile API。







审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 二进制
    +关注

    关注

    2

    文章

    707

    浏览量

    41254
  • JAVA
    +关注

    关注

    19

    文章

    2904

    浏览量

    102998
  • SQL
    SQL
    +关注

    关注

    1

    文章

    738

    浏览量

    43463
  • 数据库
    +关注

    关注

    7

    文章

    3591

    浏览量

    63373
  • JVM
    JVM
    +关注

    关注

    0

    文章

    152

    浏览量

    12129

原文标题:微服务框架之争:Quarkus 是 SpringBoot 的替代品吗?

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    寻找松下TX2-12V的替代品

    松下的效益不行了,要搬场,继电器要涨价,求替代品。哪位大侠可以帮助一下。谢谢。原来用的型号是TX2-12V。附件中是他的数据手册。
    发表于 11-17 11:42

    寻求Ubuntu13系统下软件替代品……

    下的kile软件的替代品是什么?我在ubuntu软件中心找到了一个kile,但是安装后总感觉什么都没有,模板也找不到,完全不会用,球大神给讲解下……还有,Visual Studio的替代品,做fpga
    发表于 10-26 10:06

    如何寻找芯片IS61LV51216的替代品

    贴片,44脚的IS61LV51216是一个8M容量,结构为512K*16位字长的高速率SRAM,它的替代品有?码库网上没查到呀?怎么去找呢?
    发表于 05-17 17:34

    MMBFJ176替代品??

    如题,需要寻找一个MMBFJ176替代品,用于保证电化学检测器在断电的情况下两端电位不会偏差太大。附件为MMBFJ176规格书,望大神回复下,谢谢!
    发表于 07-21 08:33

    IF增益可控放大IC,即MC1350的替代品

    MC1350是MOTO的IF AMPLIFIER,中频增益自动控制(AGC)芯片,但现在MOTO已经停产了,故本人想找它的替代品或升级版,据说MOTO 把MC1350授权给LANSDALE公司生产了(产品为ML1350),但价格翻了好几倍,接受不了,不知有没有知道替代品
    发表于 08-22 14:10

    请问仪表放大器AD624有没有便宜的完全兼容的替代品

    仪表放大器AD624有没有便宜的完全兼容的替代品?市场上这个芯片有点贵,还不太好买到,想找兼容替代品,性能稍低点也可以,能满足要求就行,求大神推荐,谢谢。
    发表于 01-23 09:27

    电解电容廉价替代方案(寻找红宝石电容替代品

    大家好公司boss让我论证一下红宝石电解电容的替代,主要是为了降低成本。请问这个器件有合适的替代品么,要做一些必要的验证么?多谢
    发表于 04-27 08:30

    是否有TDA2003的替代品

    是否有TDA2003的替代品,或者任何人都可以推荐类似的音频放大器,可以驱动低至1欧姆的负载? #TDA2003
    发表于 08-05 10:19

    如何使用ISP1763作为替代品

    已经过时,ST-Ericson提供的下一个系列是ISP1763。 ISP1760采用128引脚配置,具有16地址线和32数据线。但新的ISP1763只是64引脚,有8个地址和32个数据引脚。我们如何使用ISP1763作为替代品?这有什么替代方案吗?-谢谢
    发表于 09-04 07:00

    【资料分享】PISTORM for COMMODORE AMIGA(68000 CPU 替代品

    描述PISTORM for COMMODORE AMIGA(68000 CPU 替代品)4层PCB 项目信息: PiStorm 本身是一个适配器板,旨在与 Raspberry Pi Model
    发表于 06-17 09:41

    Commodore 6540 ROM的替代品

    的 6540 ROM 芯片组的直接替代品。我发现 D'Asaro 项目非常好且紧凑,但更难构建。此外,他仅以 PCBexpress 格式发布该项目,无法将其导出到 Gerber。由于
    发表于 09-02 07:26

    有没有制作LIS2DH12TR这个内存的替代品

    有没有制作LIS2DH12TR这个内存的替代品
    发表于 12-06 07:29

    请问有L6376PD的直接替代品吗?

    有L6376PD的直接替代品
    发表于 12-26 10:02

    请问一下有stm32f429iit6的替代品吗?

    有stm32f429iit6的替代品吗?
    发表于 01-05 06:20

    MC908JL3ECDWE的替代品是什么?

    我正在寻找 8 位 MCU MC908JL3ECDWE 的替代品,因为不建议将其用于新设计(已过时)。为了最大限度地减少工作量,我们希望减少对 28 引脚 SOIC 封装的替换和简单的代码更改
    发表于 06-05 06:17