找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1499

积分

0

好友

190

主题
发表于 6 天前 | 查看: 25| 回复: 0

SpringBoot框架是Java开发者最熟悉的企业级应用框架之一。相比之下,Quarkus作为较新的框架,可能知晓者略少。其官网宣称自己是“超音速亚原子的Java(Supersonic Subatomic Java)”,一个为OpenJDK HotSpot和GraalVM定制的Kubernetes Native Java框架,基于最佳的Java库和标准构建,旨在为容器和Kubernetes环境下的Java微服务开发带来创新。

本文将简要比较这两个Java框架——Spring BootQuarkus,分析它们的异同与特性,并通过实际测试衡量性能。最后,探讨开发者如何从Spring生态平滑过渡到Quarkus。

SpringBoot概览

Spring Boot是一个专注于企业级应用的Java框架。它简化了所有Spring项目的使用,集成了大量开箱即用的功能,极大地提升了开发者的生产力。通过减少配置和样板代码,并遵循“约定优于配置”的原则,Spring Boot能根据依赖自动配置,从而大幅缩短Java应用的开发周期。

Quarkus概览

Quarkus是另一个采用类似简化开发理念的框架,但它额外宣称能以更快的启动时间、更高的资源利用率和效率交付更小的工件。它专为云、无服务器和容器化环境优化。尽管侧重点不同,Quarkus同样能与主流Java框架良好集成。

核心差异比较

虽然两者都拥有优秀的生态集成能力,但其内部实现与架构存在差异。例如,Spring Boot提供两种Web功能:阻塞式(Servlets)和非阻塞式(WebFlux)

Quarkus也支持这两种方式,但与Spring Boot不同的是,它允许在同一个应用中混合使用阻塞和非阻塞方法。此外,反应式编程思想更深度地嵌入了Quarkus的架构中。

为了获得更准确的对比数据,我们将使用基于Spring WebFlux和Quarkus响应式功能实现的两个完全响应式应用。Quarkus的一个重要特性是支持创建原生镜像(Native Images),因此对比也将包含两个框架的原生版本。不过,Spring对原生镜像的支持尚处于试验阶段,且两者都需要GraalVM支持。

测试应用设计

测试应用实现了三个API:创建邮政编码、查询特定邮政编码信息、按城市查询邮政编码。这些API均使用前述的响应式方法实现,数据存储使用PostgreSQL

我们的目标是创建一个比简单“HelloWorld”更贴近实际复杂度的样例。数据库驱动、序列化框架等组件的实现无疑会影响对比结果,但大多数应用都需要处理这些环节。

本次比较的目的并非决出哪个框架更优,而是通过一个具体案例,分析两种实现方式的表现。

测试方案

我们将使用JMeter执行测试并分析报告,同时使用VisualVM监控应用在测试期间的资源利用率。

测试时长为5分钟,调用所有API,从预热期开始逐步增加并发用户数,直至达到1500。测试开始后会先填充数据库,然后进行查询操作。

测试计划示意图

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

测试环境规格
由于缺乏与后台进程的完全隔离,结果可能并非最优,但如前所述,本文无意进行详尽无遗的性能分析。

测试发现

从开发者体验看,两个框架都提供了良好的体验。但Spring Boot拥有更完善的文档和更丰富的社区资源,Quarkus在这方面正在快速追赶,目前仍有差距。

在关键指标上,结果如下:

关键指标对比

实验表明,Quarkus在JVM和原生版本上的启动时间几乎比Spring Boot快一倍。构建时间也显著更短:原生镜像构建,Quarkus耗时9分钟,Spring Boot为13分钟;JVM版本构建,Quarkus耗时20秒,Spring Boot为39秒。

在产物大小上,Quarkus同样领先,生成了更小的文件:原生镜像方面,Quarkus为75MB,Spring Boot为109MB;JVM版本方面,Quarkus仅4KB,Spring Boot为26MB。

在其他性能指标上,结论则不那么分明,需要进一步探究。

CPU使用率分析

在预热阶段初期,JVM版本消耗了更多CPU。之后,CPU使用率趋于稳定,所有版本的消耗水平变得相对平均。

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

Quarkus JVM CPU消耗

Quarkus Native CPU消耗

内存使用率分析

内存情况更为复杂。首先,两个框架的JVM版本显然为堆内存(Heap)预留了更多空间。尽管如此,Quarkus初始预留的内存更少,启动期间的内存占用也更低。

观察测试期间的利用率,Native版本似乎不如JVM版本那样高效或频繁地进行内存回收。这可以通过调整参数来改善,但本次比较均使用默认参数,未对GC或JVM选项做任何修改。

内存使用情况对比如下:

Spring Boot JVM内存

Quarkus JVM内存

Quarkus Native内存

尽管测试中Quarkus出现了更高的瞬时峰值,但其总体内存消耗确实更少。

响应时间分析

在响应时间和峰值线程使用数方面,Spring Boot似乎略有优势。它能够用更少的线程处理相同的负载,同时保持更优的响应时间,其Native版本在此项表现最佳。

以下是各版本的响应时间分布:

Spring Boot JVM响应时间
Spring Boot JVM版本虽然有更多异常值,但随时间推移取得了最佳进展,这很可能得益于JIT编译器的优化。

Quarkus JVM响应时间

Spring Boot Native响应时间

Quarkus Native响应时间

Quarkus在低资源消耗方面表现强劲。然而,至少在本实验中,Spring Boot在吞吐量和响应能力上与Quarkus旗鼓相当。两个框架均成功处理了所有请求,未产生任何错误,整体性能表现相近。

总结

综上所述,在实现Java应用时,这两个框架都是优秀的选择。

原生程序启动迅速、资源消耗低,非常适合无服务器、短期任务以及对资源敏感的环境。

另一方面,JVM应用程序虽然初始开销较大,但具备卓越的长期稳定性和高吞吐量,是构建健壮、长生命周期应用的理想选择。测试代码和脚本可在GitHub上找到。

从Spring迁移至Quarkus

随着云原生和Kubernetes的兴起,对原生应用支持良好的Quarkus框架越来越受到关注。许多开发者开始考虑从Spring转向Quarkus。幸运的是,Quarkus由一群拥有深厚Java技术背景的工程师创建,其中也包括为Red Hat Runtime上的Spring Boot提供支持的工程师,因此它提供了Spring API兼容性,让迁移过程更为平滑。

Spring开发者为何要考虑Quarkus?

容器化与Kubernetes的普及,促使人们重新评估Java在云原生应用开发中的地位。Kubernetes环境高度动态且资源共享,要求应用能快速启动、高效利用资源以应对频繁的扩缩容和重新部署。传统的Java云原生运行时往往在现有技术栈上层层叠加,导致内存占用大、启动慢,迫使一些公司转而采用Go或Node.js。

传统云原生Java栈

这正是Quarkus致力解决的问题。它针对内存使用率和快速启动进行了深度优化。与其它云原生Java栈相比,运行于JVM的Quarkus应用能在同等内存下部署近两倍的实例;当打包为原生二进制文件时,实例数量甚至可提升7倍。这不仅是通过GraalVM编译为原生那么简单,Quarkus从根本上优化了传统“高度动态”框架以适应Kubernetes基础设施,显著降低了内存利用并加快了启动速度。这些经过优化、文档齐全的组件在Quarkus中被称为“扩展”。

运行时效率对比

Quarkus技术栈

迁移至Quarkus的实践考量

以某公司的实际迁移为例,其旧系统基于Spring和Tomcat,在维护和部署中遇到诸多挑战,出于以下原因决定迁移至Quarkus:

  • 资源消耗:Spring/Tomcat框架为应用核心功能之外的操作消耗了过多的内存和CPU。
  • 预热时间长:Spring应用可能需要10-20秒才能启动完毕并开始预热。
  • 样板代码:减少了开发者厌恶的冗余代码。
  • 测试便捷性:使用@QuarkusTest注解可轻松启动整个应用进行集成测试。
  • 横向扩展优势:应用资源占用越小,在集群中可部署的实例就越多。
  • 学习曲线平缓:Quarkus在线文档简明易懂。

Spring开发者可沿用的知识

Quarkus的Spring API兼容性目前涵盖Spring DI、Spring Web和Spring Data JPA,并计划支持Spring Security、Spring Config等。在JVM上运行时,Quarkus应用几乎可以利用任何Java库;只要库不大量使用Java反射,它们也能被编译为原生,例如Lombok。需要明确,Quarkus的Spring API兼容性并非旨在完整复刻Spring平台以直接托管旧应用,而是为了让新项目基于Quarkus开发时,Spring开发者能感到自然和熟悉。结合众多预优化的扩展,Quarkus为微服务开发提供了强大功能,已有许多成功迁移案例。

Spring框架本质上是高度动态的。为此,Quarkus的Spring兼容性扩展将Spring API映射到已经过优化(快速启动、低内存、原生编译)的现有扩展(如RESTEasy、CDI)中的API,并且不使用Spring应用上下文。因此,尝试引入额外的、未经适配的Spring库可能无法正常工作。

Quarkus Spring Web 示例

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 示例

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 容错示例

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();
    }
}

给Spring开发者的额外价值

除了提升资源利用率和启动速度,Quarkus还为Spring开发者带来以下好处:

  • 函数即服务(FaaS)友好:编译为原生二进制文件后,Quarkus应用可在毫秒级(如0.0015秒)内启动,使得利用现有Spring/Java知识开发FaaS函数成为可能。
  • 实时编码:支持开发热重载,修改代码后保存,刷新浏览器即可看到变化,无需重启应用,且与IDE无关。
  • 反应式与命令式混合编程:Quarkus拥有反应式核心,支持纯命令式、纯反应式或两者混合的编程模型。
  • 编译期依赖注入检查:在编译阶段而非运行时捕获依赖注入错误,提前发现问题。
  • 融合最佳框架与标准:支持在同一应用中组合使用Spring API、Eclipse Vert.x、MicroProfile(JAX-RS、CDI等)、反应式流等多种技术。

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

建议按照以下步骤入门:

  1. 阅读官方入门指南了解Quarkus概貌。
  2. 深入学习Spring DISpring WebSpring Data JPA的兼容性指南。
  3. 使用Quarkus应用生成器快速创建新项目。



上一篇:深入理解LoRA原理与Multi-LoRA实战:从低秩适配到多任务部署
下一篇:Nginx并发性能优化四大核心参数详解:构建百万级高并发架构
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-24 17:17 , Processed in 0.165633 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表