Quarkus 替代 SpringBoot

news2024/12/23 17:09:40
  • 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] 创建一个新应用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mp4视频批量截取!!!

mp4视频批量截取&#xff01;&#xff01;&#xff01; 问题&#xff1a;如果我们想截取一个mp4视频中的多个片段&#xff0c;一个一个截会很麻烦&#xff01; 可以将想要截取的开始时间和结束时间保存到 excel表 中&#xff0c;进行批量截取。 1、对一个视频&#xff0c;记…

临床决策分析(DCA)演示APP:理解DCA分析

临床决策分析&#xff08;DCA&#xff09;演示APP&#xff1a;理解DCA分析 之前讨论了DCA分析的分析过程和作用&#xff0c;认为其最主要的作用是确定预测模型的决策阈值&#xff0c;从而促进预测模型与临床的结合。DCA的影响不止于此&#xff0c;在DCA分析中&#xff0c;预测…

C++模拟实现——红黑树

一、介绍 红黑树也是对一般的搜索二叉树不能保证平衡的一个改进&#xff0c;和AVL树采用的思路不同&#xff0c;但同样需要旋转&#xff0c;其本质也是一颗平衡搜索二叉树&#xff0c;其节点有颜色的区分&#xff0c;并且被一些规则束缚&#xff0c;在这些规则下&#xff0c;能…

远勤山丨于无声处听惊雷——写在远航汽车投产下线之际

“只要未来有前途的产业必然竞争激烈。新能源汽车目前还有很多新进入者&#xff0c;证明还有很大的成长空间。对于远航汽车&#xff0c;我们非常有信心坐上最后的牌桌。” 2023年11月8日&#xff0c;在山西运城大运新能源生产基地举办的“远航汽车下线仪式”上&#xff0c;大运…

举报“将我的电脑控作己用者”!

既然“麻辣800727”都说是“街子电信”干的&#xff0c;那么&#xff0c;我现在就正式举报&#xff1a;请依法管理宽带网&#xff0c;你国营的也不可以随意侵犯用户的人权&#xff0c;更不可以将自己变成法外之地&#xff01; 请公开答复&#xff0c;并改正&#xff0c;否则把…

Web实验(总)

目录 网站需求&#xff1a; 思路&#xff1a; 实验步骤&#xff1a; 第一步&#xff1a;准备工作 第二步&#xff1a;新建一个存储网页的目录 第三步&#xff1a;修改本地hosts映射 第四步&#xff1a;修改配置文件&#xff0c;建立基于http服务的网站 1)创建用户song和…

都快2024年了,别只使用React,需要学习一下Vue,不然没出路了

最近&#xff0c;我的朋友因为不熟悉 Vue.js 而未能通过面试。 她平时工作中大部分时间都在使用React&#xff0c;所以也懒得去了解其他前端框架。 世界上所有的前端框架我们都应该熟悉吗&#xff1f; 不&#xff0c;这是极其不合理的。 但为了生存&#xff0c;朋友还是要学…

Vue事件绑定

目录 前言 Vue事件处理 指令的语法格式 事件绑定指令—v-on 回调函数 前言 我们知道如何在原生js中实现事件绑定&#xff0c;那在vue中如何实现呢&#xff1f; Vue事件处理 指令的语法格式 <标签 v-指令名&#xff1a;参数名"表达式">{{插值语法}}</…

2D 3D 工业组态技术 meta2d JavaScript

本心、输入输出、结果 文章目录 2D 3D 工业组态技术 meta2d JavaScript前言2D 3D 工业组态技术 meta2d JavaScript 简介2D 3D 工业组态技术 meta2d JavaScript 特性丰富的组态能力0代码数据通信组态的应用多端适配能力强大的扩展能力追求卓越性能丰富的组件库资源广泛的应用场景…

React Virtual DOM及Diff算法

JSX到底是什么 使用React就一定会写JSX&#xff0c;JSX到底是什么呢&#xff1f;它是一种JavaScript语法的扩展&#xff0c;React使用它来描述用户界面长成什么样子&#xff0c;虽然它看起来非常像HTML&#xff0c;但他确实是javaScript&#xff0c;在React代码执行之前&#…

介绍几种Go语言开发的IDE

文章目录 1.前言2.几种ide2.1 Goland2.2 VsCode示例 2.3 LiteIDE2.4 Eclipse插件GoClipse2.5 Atom2.6 Vim2.7 Sublime Text 3.总结写在最后 1.前言 Go语言作为一种新兴的编程语言&#xff0c;近年来受到了越来越多的关注。 它以其简洁、高效和并发性能而闻名&#xff0c;被广…

基于STC12C5A60S2系列1T 8051单片机的数模芯片DAC0832实现数模转换应用

基于STC12C5A60S2系列1T 8051单片机定时器/计数器应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍数模芯片DAC0832介绍通过按键调节数模芯片DAC0832输出模拟量控制…

ThreadLocal原理及使用场景

ThreadLocal意为线程本地变量&#xff0c;用于解决多线程并发时访问共享变量的问题 明显&#xff0c;在多线程的场景下&#xff0c;当有多个线程对共享变量进行修改的时候&#xff0c;就会出现线程安全问题&#xff0c;即数据不一致问题。常用的解决方法是对访问共享变量的代码…

dll文件【C#】

加载方法&#xff1a; [DllImport("controlcan.dll")] public static extern UInt32 VCI_OpenDevice(UInt32 DeviceType, UInt32 DeviceInd, UInt32 Reserved); 文件存放位置&#xff1a; 一般放Debug文件夹下。 运行错误&#xff1a; 原因是CPU位数选择不对&…

F8652X 984865265 F8652E 984865264

F8652X 984865265 F8652E 984865264 亚历克能够满足最严格的建筑规范开箱-不需要大量的定制&#xff0c;设计时间或劳动力&#xff0c;或专门的布线系统。 模块化ALEC系统包括三个简单的硬件组件——区域控制器(ZC001)、标准按钮墙板和物联网(IoT)网关。该系统可以无限扩展&…

Python高级语法----高级Python函数式编程

文章目录 1. 函数式编程概念2. 使用functools模块3. 深入理解lambda, map, filter, reduce函数a. lambda 函数b. map 函数c. filter 函数d. reduce 函数1. 函数式编程概念 函数式编程是一种编程范式,它将计算视为函数的评估,并避免使用程序状态及可变数据。在Python中,函数…

【VS Code插件开发】创建终端(八)

🐱 个人主页:不叫猫先生,公众号:前端舵手 🙋‍♂️ 作者简介:前端领域优质作者、阿里云专家博主,共同学习共同进步,一起加油呀! ✨优质专栏:VS Code插件开发极速入门 📢 资料领取:前端进阶资料可以找我免费领取 目录 一、createTerminal创建终端二、终端方法1、…

警方打击了大规模网络钓鱼提供商BulletProftLink

导语 最近&#xff0c;马来西亚皇家警察宣布成功打击了一个名为BulletProftLink的大规模网络钓鱼提供商。这个提供超过300个钓鱼模板的平台被查封&#xff0c;给全球网络安全带来了巨大的利好消息。本文将带您了解这个引人注目的行动背后的故事&#xff0c;并揭示BulletProftLi…

根据特定规则生成合并数据,遍历循环时会存在数据错乱等情况的问题排查(深拷贝 仅自己记录)

问题前景 在合并生成领料单&#xff0c;选择相同物料&#xff0c;合并领料&#xff0c;但因批次&#xff0c;数量不一样&#xff0c;需要单独生成一个主单据下面显示具体的物料&#xff0c;主单据的数量必须是选择单据的数量累加 错误代码演示 const temp JSON.parse(JSON…

YOLOV5中parser参数配置

源码下载链接&#xff1a;ultralytics/yolov5: YOLOv5 &#x1f680; in PyTorch > ONNX > CoreML > TFLite (github.com) 需要配置的参数&#xff1a;--data parser.add_argument(--data, ...)&#xff1a;添加一个用于数据配置文件的路径的参数。 可以直接修改&am…