超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。

这篇具有很好参考价值的文章主要介绍了超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

来源:juejin.cn/post/7023317351563001886

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 应用程序的开发周期。

Spring Boot 基础就不介绍了,推荐看这个实战项目:

https://github.com/javastacks/spring-boot-best-practice

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

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。

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

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。

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

5、调查结果

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

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

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。

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

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。JVM 版的 Quarkus ↑↑↑

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。Native 版的 Quarkus ↑↑↑

内存

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

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

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

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。Spring Boot JVM ↑↑↑

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。Quarkus JVM ↑↑↑

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。Spring Boot 原生 ↑↑↑

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。Quarkus 原生 ↑↑↑

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

响应时间

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

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

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。Spring Boot JVM ↑↑↑

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

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。Quarkus JVM ↑↑↑

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。Spring Boot 原生 ↑↑↑

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。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 提供支持的工程师。

推荐一个开源免费的 Spring Boot 实战项目:

https://github.com/javastacks/spring-boot-best-practice

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

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

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

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。传统云原生 Java 栈 ↑↑↑

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

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

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

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。运行时效率 ↑↑↑

超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。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 库可能不会奏效。

推荐一个开源免费的 Spring Boot 实战项目:

https://github.com/javastacks/spring-boot-best-practice

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] 创建一个新应用。

参考资料:

  • https://www.baeldung.com/spring-boot-vs-quarkus
  • https://quarkus.io/blog/quarkus-for-spring-developers/
  • https://www.logicmonitor.com/blog/quarkus-vs-spring

近期热文推荐:

1.1,000+ 道 Java面试题及答案整理(2022最新版)

2.劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

5.《Java开发手册(嵩山版)》最新发布,速速下载!

觉得不错,别忘了随手点赞+转发哦!文章来源地址https://www.toymoban.com/news/detail-746378.html

到了这里,关于超音速亚原子 Java 框架来了,0.0015 秒内启动一个应用,太快了。。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 你对java的原子性了解多少?

    在Java中,原子性是指一个操作是不可被中断的整体操作。原子性确保一个操作在多线程环境下执行时,不会被其他线程干扰,要么完全执行成功,要么完全不执行。 Java提供了多种机制来实现原子性操作: volatile:使用volatile修饰的变量可以保证变量的可见性,并且对

    2024年02月04日
    浏览(38)
  • 【正点原子STM32】认识HAL库(CMSIS、STM32Cube固件包、HAL库框架结构、使用HAL库、注意事项)

    一、初识HAL库 1.1、CMSIS简介 1.2、HAL库简介 二、STM32Cube固件包浅析 2.1、如何获取STM32Cube固件包? 2.2、STM32Cube固件包文件夹简介 2.3、CMSIS文件夹关键文件 三、HAL库框架结构 3.1、HAL库文件夹结构 3.2、HAL库文件介绍 3.3、HAL库API函数和变量命名规则 四、如何使用HAL库 4.1、基于CM

    2024年02月21日
    浏览(45)
  • 面试专题:java多线程(3)---关于 Atomic 原子类

    1.介绍一下Atomic 原子类Atomic     翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里  Atomic   是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰

    2024年02月07日
    浏览(58)
  • Java中单例(单态、原子)设计模式(饿汉式/懒汉式)

    先看文章目录,大致了解知识点结构,直接点击文章目录可以跳转到文章指定位置。 设计模式就是设计出来的固定问题的解决方法,描述了在软件设计过程中的一些不断重复发生的问题和解决方案。遇到类似问题的时候可以直接使用现成的模式方案。 ①单例模式中一个类只

    2024年02月04日
    浏览(43)
  • java八股文面试[多线程]——并发三大特性 原子 可见 顺序

        AutomicInteger :  volatile + CAS 总线LOCK  MESI 两个协议 TODO volatile的可见性和禁止重排序是怎么实现的: DCL场景:  new操作会在字节码层面生成两个步骤: 分配内存、调用构造器 然后把引用赋值给singleton 不加volatile则会发生指令重排,可能得到不完整的对象 知识来源: 【并

    2024年02月11日
    浏览(53)
  • 【正点原子STM32】STM32基础知识(F1F4F7H7 STM32系统框架、寻址范围、存储器映射的存储器功能划分、寄存器映射)

    一、STM32系统框架 1.1、Cortex M内核 芯片 1.2、F1系统架构 1.3、F4系统架构 1.4、F7系统架构 1.5、H7系统架构 二、STM32的寻址范围? 三、存储器映射 存储器功能划分(F1为例) STM32F1存储器映射图 四、寄存器映射 寄存器基础知识 STM32寄存器分类 寄存器映射(F1为例) 寄存器描述解

    2024年02月21日
    浏览(54)
  • Java进阶(6)——抢购问题中的数据不安全(非原子性问题)& Java中的synchronize和ReentrantLock锁使用 & 死锁及其产生的条件

    1.大量请求拥挤抢购中的数据不安全问题; 2.事务ACID:原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durability); 3.线程安全特征:原子性(Atomicity)可见性(Visibility)有序性(Ordering); 4.java中的锁初步,synchronize锁和ReentrantLock锁使用初步; 5.滥用锁的问

    2024年02月11日
    浏览(41)
  • 【走进Java框架】什么是Java框架,为什么要学习Java框架.

    前言: 大家好,我是 良辰丫 ,今天我们就要开始Java框架之旅了,我们在学习的征途中不断充实自己,提升自己的能力,加油哈,自我勉励一下,跟随我的步伐,一起前行哈.💌💌💌 🧑个人主页:良辰针不戳 📖所属专栏:javaEE进阶篇之框架学习 🍎励志语句:生活也许会让我们遍体鳞

    2024年02月07日
    浏览(43)
  • java框架 - Servlet基础框架

    一,servlet定义         Servlet(Server Applet)是Java Servlet的简称,称为服务器端小程序、小服务程序或服务连接器,是一种使用 Java 语言来开发动态网站的技术(用Java编写的服务器端程序),具有独立于平台和协议的特性,Servlet是sun公司提供的一门用于开发动态web资源的技术

    2024年02月04日
    浏览(45)
  • 《JUC并发编程 - 高级篇》05 -共享模型之无锁 (CAS | 原子整数 | 原子引用 | 原子数组 | 字段更新器 | 原子累加器 | Unsafe类 )

    有如下需求,保证 account.withdraw 取款方法的线程安全 原有实现并不是线程安全的 测试代码 执行测试代码,某次执行结果 5.1.1 为么不安全 withdraw 方法是临界区,会存在线程安全问题 查看下字节码 多线程在执行过程中可能会出现指令的交错,从而结果错误! 5.1.2 解决思路1

    2023年04月12日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包