Quarkus 替代 SpringBoot

  • 1 概述
  • 2 SpringBoot
  • 3 Quarkus
  • 4 比较
  • 5 调查结果
  • 6 从 Spring 转换到 Quarkus
  • 7 我是 Spring 开发者,为什么要选Quarkus?
  • 8 Spring 开发者可以活用哪些现有知识?
  • 9 对Spring开发者有额外的好处吗?
  • 10 Spring开发者如何开始学习Quarkus?

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。我们将在前几秒钟开始填充数据库,然后开始查询,如下所示:

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

5 调查结果

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

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

图片

通过这个实验,我们可以观察到 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 消耗:

JVM 版的 Quarkus ↑↑↑

Native 版的 Quarkus ↑↑↑

内存

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

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

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

Spring Boot JVM ↑↑↑

Quarkus JVM ↑↑↑

Spring Boot 原生 ↑↑↑

Quarkus 原生 ↑↑↑

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

响应时间

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

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

Spring Boot JVM ↑↑↑

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

Quarkus JVM ↑↑↑

Spring Boot 原生 ↑↑↑

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 重新培养人才和开发工具。

传统云原生 Java 栈 ↑↑↑

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

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

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

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

import java.util.List;
import java.util.Optional;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/person")
public class PersonController {
    @GetMapping(path = "/greet/{id}", produces = "text/plain")
    public String greetPerson(@PathVariable(name = "id") long id) {
        String name="";
        // ...
        return name;
    }

    @GetMapping(produces = "application/json")
    public Iterable<Person> findAll() {
        return personRepository.findAll();
    }

Quarkus Spring Repository Example

package org.acme.springmp;

import java.util.List;
import org.springframework.data.repository.CrudRepository;

public interface PersonRepository extends CrudRepository<Person, Long> {
    List<Person> findByAge(int age);
}

Quarkus Spring Service + MicroProfile Fault Tolerance Example

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

@Service                                            // Spring
public class PersonService {

    @Autowired                                      // Spring
    @RestClient                                     // MicroProfile
    SalutationMicroProfileRestClient salutationRestClient;

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

    @CircuitBreaker(delay=5000, failureRatio=.5)    // MicroProfile
    @Fallback(fallbackMethod = "salutationFallback")// MicroProfile
    public String getSalutation() {
        return salutationRestClient.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。

10 Spring开发者如何开始学习Quarkus?

推荐的步骤包括:

  • 参看入门指南 [4]作为 Quarkus 的一般介绍。
  • 参看 Spring DI [5]、Spring Web [6] 和 Spring Data JPA [7] 的指南。
  • 使用 code.quarkus.io [8] 创建一个新应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/144904.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

libgdx实现雪花、下雪效果(二十三)

libgdx实现雪花、下雪效果&#xff08;二十三&#xff09; 转自&#xff1a;https://lingkang.top/archives/libgdx-shi-xian-xue-hua package effect;import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.backends.lwjgl3.…

使用CXF调用WSDL(二)

简介 本篇文章主要解决了上篇文章中遗留的对象嵌套问题&#xff0c;要想全面解析无限极的对象嵌套需要使用递归去解决 上文链接&#xff1a; 使用CXF调用WSDL&#xff08;一&#xff09; 上文回顾 上文使用了单方法“ call() ”解决了List和基本类型&#xff08;含String&…

基于逐次变分模态分解(SVMD)联合小波阈值去噪

代码原理 逐次变分模态分解 (Iterative Variational Mode Decomposition, IVMD) 是一种信号分解方法&#xff0c;它可以将一个时域信号分解为若干个本征模态函数&#xff08;Intrinsic Mode Functions, IMF&#xff09;。它通过迭代寻找信号的本征模态函数和残差部分&#xff…

Kalman滤波

文章目录 一、公式推导二、扩展卡尔曼滤波 卡尔曼滤波是一种最优化递归数据处理算法。&#xff08;Optimal Recursive Data Processing Algorithm&#xff09; Kalman滤波是时域滤波&#xff0c;采用状态空间描述系统&#xff0c;运用递推形式是计算简单&#xff0c;数据存储量…

TSINGSEE视频汇聚管理与AI算法视频质量检测方案

一、建设背景 随着互联网视频技术的发展&#xff0c;视频监管在辅助安全生产、管理等方面发挥了不可替代的作用。但是&#xff0c;在监管场景中&#xff0c;仍然存在视频掉线、视频人为遮挡、视频录像存储时长不足等问题&#xff0c;对企业的日常管理和运转存在较大的安全隐患…

A. Weird Sum

题目链接 : Problem - 1648A - Codeforces 题面 : 题意 : 输入 n m (1≤n*m≤1e5) 和 n 行 m 列的矩阵 a&#xff0c;元素范围 [1,1e5]。 对于矩阵中的所有相同元素对&#xff0c;即满足 a[x1][y1] a[x2][y2] 的元素对 (a[x1][y1], a[x2][y2])&#xff0c;把 abs(x1-x2)…

P3371 【模板】单源最短路径(弱化版)

【模板】单源最短路径&#xff08;弱化版&#xff09; 题目背景 本题测试数据为随机数据&#xff0c;在考试中可能会出现构造数据让SPFA不通过&#xff0c;如有需要请移步 P4779。 题目描述 如题&#xff0c;给出一个有向图&#xff0c;请输出从某一点出发到所有点的最短路…

代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和

LeetCode T1143 最长公共子序列 题目链接:1143. 最长公共子序列 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 动规五部曲分析 1.确定dp数组的含义 这里dp数组的含义是结尾分别为i-1,j-1的text1和text2的最长公共子序列长度 至于为什么是i-1,j-1我之前已经说过了,这里再…

ABZ正交编码 - 异步电机常用的位置信息确定方式

什么是正交编码&#xff1f; ab正交编码器&#xff08;又名双通道增量式编码器&#xff09;&#xff0c;用于将线性移位转换为脉冲信号。通过监控脉冲的数目和两个信号的相对相位&#xff0c;用户可以跟踪旋转位置、旋转方向和速度。另外&#xff0c;第三个通道称为索引信号&am…

μC/OS-II---计时器管理2(os_tmr.c)

目录 获取计时器的名字获取计时器到期前剩余的时间查看计时器的状态 计时器是倒计时器&#xff0c;当计数器达到零时执行某个动作。用户通过回调函数提供这个动作。回调函数是用户声明的函数&#xff0c;在计时器到期时被调用。在回调函数中绝对不能进行阻塞调用&#xff08;例…

软件测试基础1:认识软件及测试

功能测试能力:具备对所有软件的功能进行质量验证。 1什么是软件 分类 应用软件系统软件 软件&#xff1a;控制计算机硬件工作的工具。 2软件基本组成 3软件产生过程 4什么是软件测试 软件测试&#xff1a;使用技术手段验证软件是否满足使用需求。 5软件测试目的 减少软件…

使用matlab制作声音采样率转换、播放以及显示的界面

利用matlab做一个声音采样率转换、播放以及显示的界面 大抵流程&#xff1a; 图形界面创建&#xff1a;使用figure函数创建名为“声音采样率转换”的图形界面&#xff0c;并设置了其位置和大小。 按钮和文本框&#xff1a;使用uicontrol函数创建了选择音频文件的按钮、显示当前…

工业数据的“最后一公里”怎么走?

随着工业互联网的迅猛发展&#xff0c;工业数据已经成为推动制造业转型升级的重要动力。然而&#xff0c;面对海量的工业数据&#xff0c;如何高效、准确地走过数据的“最后一公里”&#xff0c;成为制约企业发展的关键问题。本文将探讨工业数据“最后一公里”所面临的挑战&…

魔兽服务器学习-笔记(服务器部署、地图管理、DB、日志模块、任务模块、战斗模块)

文章目录 一、环境准备1&#xff09;依赖安装2&#xff09;源码下载和编译 二、生成数据信息1&#xff09;地图数据信息&#xff08;客户端信息&#xff09;2&#xff09;数据库信息 三、启动服务器四、日志模块五、数据库模块六、场景模块1&#xff09;地图管理2&#xff09;A…

如何在微信内置浏览器内抓包

文章目录 使用环境&工具使用步骤1、手机USB连接上电脑&#xff0c;打开USB调试2、解压adb工具的压缩包&#xff0c;使用该工具连接上手机3、开启微信抓包4、电脑上打开chrome内核的浏览器或edge浏览器 使用环境&工具 windows电脑 安卓手机 adb工具 USB数据线 使用步骤…

【已解决】git push send-pack: unexpected disconnect while reading sideband packet

解决办法&#xff1a;修改缓存大小 打开项目所在路径下的git目录 找到config文件&#xff0c;用记事本打开编辑。 添加如下内容并保存即可 [http] postBuffer 1048576000

每日一练:Python中实现将阳历转换为农历

农历是中国传统的农业历法&#xff0c;与阳历&#xff08;公历&#xff09;有所不同。在Python中&#xff0c;我们可以使用第三方库 lunardate 来实现阳历到农历的转换。以下是一个简单的示例&#xff0c;演示如何在Python中执行这个转换过程。 1.安装 lunardate 库 首先&…

VR全景:打造虚拟政务服务,打通服务群众“最后一公里”

大家对政务大厅的工作效率可能已经司空见惯&#xff0c;办事窗口少&#xff0c;而需要办理的群众和业务却很多&#xff0c;很多去政务大厅办理业务的&#xff0c;排队几个小时也是常有的。并且在传统政务服务中&#xff0c;办事流程一般都较为复杂、耗时长&#xff0c;往往需要…

基于SSM的宠物领养系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

高频CSS面试题

给大家推荐一个实用面试题库 1、前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;web前端面试题库 BFC 块级格式上下文(block format context)是页面一块独立的渲染区域&#xff0c;具有一套独立的渲染规则 内部的…