为什么越来越多人用Quarkus?

前言

前段时间有位球友说他们内部在做Java技术栈的"瘦身"评估,让我帮忙看看几个候选框架。

我问他为什么要做这件事,他给我算了一笔账。

他们公司跑着两百多个Spring Boot服务,每个服务平均占用512MB内存,按K8s节点规格折算下来,光是JVM堆内存的闲置浪费,一年就要多花几十万。

更别提每次滚动发布,几百个Pod要同时重启,光是"等服务启动完成"这个环节,发布窗口就要预留半个小时。

"不是Spring Boot不好用,"他说,"是我们现在跑的这套东西,跟云原生这个环境,有点水土不服了。"

这句话我琢磨了很久。

Spring Boot当然没有"过时",它的问题是设计初衷和云原生环境之间存在结构性错配。

今天这篇文章,我就把Quarkus为什么越来越多人用的原因,从头到尾给你拆解一遍。

一、Java框架在云原生环境下的困境

有些小伙伴可能会说:"Spring Boot用了这么多年,好好的啊,为什么要换?"

Spring Boot当然好。

但在云原生环境下,它继承的那套运行时反射模型 ,和Kubernetes的弹性伸缩模型之间存在根本性的错配。

具体来说,传统Java应用在云原生环境下面临三重困境:

第一重:启动时间困境。

Spring Boot应用动辄需要5到15秒才能完成上下文初始化,这期间类加载、Bean实例化、依赖注入、自动配置扫描等大量工作在主线程上串行执行,而JIT编译器还未介入,解释执行的开销进一步放大了启动延迟。

第二重:内存占用困境。

一个最简单的Spring Boot Web应用常驻内存往往超过200MB,而同等功能的Go应用可能只需要20MB。在Kubernetes集群中,内存是按副本数线性计费的,每个副本多200MB,百副本规模每月就是数千美元的成本。

第三重:预热困境。

即便应用启动完成,JIT编译器需要数千次方法调用才能识别热点并触发编译,应用在启动后的前几分钟内吞吐量可能只有稳定期的30%到50%。对于按需扩缩容的场景,新副本刚启动就承接流量会导致请求超时。

这三重困境的根源不在于Java语言本身,而在于Java生态长期沿用的运行时反射模型。

Spring、Hibernate、Jackson等几乎所有主流框架都依赖反射在运行时扫描类路径、解析注解、动态生成代理。这种模型在开发期极其灵活,但在运行期却要付出沉重的代价。

二、Quarkus的构建期处理架构

Quarkus的核心贡献之一,就是重新设计了一套完全构建期化的框架内核,使得应用天然满足Native Image的闭世界假设,从而让Native Image真正可用于生产级Java应用。

用人话说:Spring Boot把活儿留到运行时干,Quarkus在构建时就把活儿干完了。

三、底层原理

3.1 构建期处理全流程

这张图展示了Quarkus从源码到运行时的完整链路,核心思想是把所有重量级工作前移到构建阶段:

对比Spring Boot的运行时流程:Spring Boot在启动时执行"扫描→解析→构建Bean定义→反射创建→注入"全链路,而Quarkus把前四步全部挪到了构建阶段,运行时只做"加载预生成代码"这一步。

这就是启动时间从5.6秒降到1.3秒的根本原因。

3.2 ArC依赖注入:构建时代码生成 vs 运行时反射

这张图对比了Spring DI和Quarkus ArC在Bean创建上的本质差异:

关键理解 :ArC在构建时就"知道"GreetingService依赖GreetingBean,它直接生成new GreetingService(new GreetingBean())的字节码。

运行时不需要反射查找构造器、不需要反射注入字段、不需要动态生成代理。

依赖注入从"运行时操作"变成了"编译期生成的代码"。

3.3 虚拟线程调度模型

Quarkus 4以Java 21为基线,虚拟线程成为一等公民。

这张图展示了虚拟线程与传统平台线程的调度差异:

在Quarkus中使用虚拟线程:

java 复制代码
@RunOnVirtualThread
@GET
@Path("/blocking-operation")
public String blockingOperation() {
    // 这段代码运行在虚拟线程上
    // 可以使用简单的阻塞API
    // 同时获得极高的并发能力
    return repository.findSomething();
}

核心价值:传统平台线程每个请求占用1MB栈内存,阻塞时线程空转。

虚拟线程是M:N调度------大量虚拟线程复用少量载体线程,阻塞时自动挂起,载体线程去跑其他虚拟线程。

这意味着你可以继续写简单的阻塞代码,同时获得接近响应式编程的并发能力。

四、性能数据

4.1 官方基准测试(2026年3月)

指标 Quarkus Spring Boot 差距
吞吐量 19,255 tps 7,238 tps 2.7倍
JVM启动 2.9秒 6.6秒 2.3倍
内存占用 269MB 583MB 2.2倍

4.2 BMW Romania的独立实测(2026年8月)

BMW Romania的CTO Alex Diniș做了一个非常严谨的对比测试:同一个服务,用Spring Boot和Quarkus各写一遍,包含相同的REST端点、业务逻辑和嵌入式ML情感分类模型。

指标 Quarkus Spring Boot 差距
JVM启动 1.3秒 5.6秒 4.3倍
Native启动 ~200ms ~2s 10倍
空闲内存 88MB 204MB 2.5倍
Docker镜像 更小 更大 ---

这些数字在实际业务中的影响 :假设每天200次扩容事件,每次2个Pod,Spring Boot和Quarkus之间4.3秒的启动差距,乘以400次Pod启动,每天多出约30分钟的不可服务时间。

按每秒50个请求算,这相当于每天约10万个延迟或失败的请求。

五、代码实战

5.1 项目创建

bash 复制代码
mvn io.quarkus.platform:quarkus-maven-plugin:3.38.0:create \
    -DprojectGroupId=com.example \
    -DprojectArtifactId=quarkus-demo \
    -Dextensions='resteasy-reactive,resteasy-reactive-jackson,hibernate-orm-panache,jdbc-postgresql'

5.2 写一个REST接口

java 复制代码
package com.example.resource;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello from Quarkus!";
    }
}

5.3 实体和Repository(Panache风格)

java 复制代码
// 实体
@Entity
@Table(name = "products")
public class Product extends PanacheEntity {
    public String name;
    public BigDecimal price;
    public Integer stock;
}

// Repository(Panache风格,无需写实现)
@ApplicationScoped
public class ProductRepository implements PanacheRepository<Product> {

    public List<Product> findInStock() {
        return find("stock > 0").list();
    }

    public List<Product> findByName(String name) {
        return find("name", name).list();
    }
}

5.4 Service层

java 复制代码
@ApplicationScoped
public class ProductService {

    @Inject
    ProductRepository productRepository;

    public List<Product> getInStockProducts() {
        return productRepository.findInStock();
    }

    @Transactional
    public Product createProduct(Product product) {
        product.persist();
        return product;
    }
}

5.5 配置(application.properties)

properties 复制代码
quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=postgres
quarkus.datasource.password=postgres
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/mydb

quarkus.hibernate-orm.database.generation=update

5.6 运行

bash 复制代码
# 开发模式(支持热重载)
./mvnw quarkus:dev

# 打包为JVM模式
./mvnw package

# 打包为Native镜像
./mvnw package -Pnative

六、优缺点

优点

1. 启动速度颠覆性提升

JVM模式1.3秒,Native模式200毫秒。对于K8s弹性伸缩场景,这是从"分钟级"到"秒级"的质变。

2. 内存占用大幅降低

空闲内存88MB,是Spring Boot的2.5倍差距。在K8s集群中,每个副本节省100MB内存,百副本规模每月节约数千美元。

3. 构建期处理带来运行时确定性

Spring Boot的运行时灵活性是一把双刃剑------你可以通过条件注解动态决定Bean是否注册,但这也意味着启动时的行为不可预测。Quarkus把所有决策前移到构建期,运行时行为完全确定。

4. 统一的命令式与响应式编程模型

Quarkus通过Eclipse Vert.x集成了命令式和响应式模型,同时仍然遵循MicroProfile和Jakarta EE标准。

5. 开发模式的热重载体验

Quarkus Dev Mode支持代码、配置和资源的实时修改,无需重建或重启,提供即时反馈。

6. Java 21虚拟线程一等公民

Quarkus 4以Java 21为基线,虚拟线程获得原生支持,不再是"二等公民"。

7. Native Image生产就绪

Quarkus从设计之初就围绕构建期处理和GraalVM原生编译构建,是Native Image最成熟的Java框架。

缺点

1. 生态成熟度不如Spring Boot

Quarkus的社区规模和第三方集成数量与Spring Boot还有差距。很多企业内部的自研中间件可能只有Spring Boot的Starter。

2. Native Image的工程成本

原生镜像构建显著更慢,调试原生可执行文件仍然困难,需要GDB和调试符号。不是所有Java特性都能开箱即用。

3. 动态性限制

构建期处理意味着运行时的动态能力受限。某些依赖运行时反射的第三方库可能需要额外的配置或适配。

4. 学习曲线

从Spring Boot迁移到Quarkus需要理解一套新的编程模型和依赖注入机制,虽然标准API兼容,但习惯需要时间调整。

5. Kotlin开发者受限

Quarkus对Kotlin的支持不如Spring Boot那么原生和成熟。

七、适用场景

场景 推荐程度 理由
K8s弹性伸缩服务 ✅✅✅ 强烈推荐 200ms启动让扩容真正"弹"得起来
Serverless/FaaS ✅✅✅ 强烈推荐 启动时间从"秒级"到"毫秒级"
高密度部署 ✅✅✅ 强烈推荐 内存占用是Spring Boot的一半
AI推理服务 ✅✅✅ 强烈推荐 快速启动+低延迟,适合模型服务
金融交易系统 ✅✅✅ 强烈推荐 高吞吐+低延迟,响应时间稳定
长期运行的核心服务 ⚠️ 需评估 启动时间差距不显著,Spring Boot生态更成熟
依赖大量Spring生态组件 ⚠️ 需评估 迁移成本可能较高
Kotlin为主的项目 ⚠️ 需评估 Quarkus对Kotlin支持不如Spring Boot

八、写在最后

回到最初的问题:为什么越来越多人用Quarkus?

答案不复杂------因为它重新思考了Java在云原生时代的运行时模型。

Spring Boot的设计哲学是"运行时灵活性优先",通过反射和运行时扫描换取开发期的便利。

这在单体应用时代是正确的选择。

但在Kubernetes时代,启动时间、内存占用、弹性伸缩速度成为了硬约束,运行时反射模型的代价开始变得不可接受。

Quarkus的设计哲学是"构建期确定性优先",把所有分析工作前移到构建阶段,运行时只执行预生成的字节码。

JVM模式1.3秒启动,Native模式200毫秒启动------这个数字意味着什么?

意味着你可以把Java应用部署在Serverless平台上,意味着K8s扩容可以在几秒内完成,意味着内存密度可以翻倍。

当然,Quarkus不是银弹。

生态成熟度、Native Image的工程成本、动态性限制都是真实存在的短板。

但对于K8s弹性伸缩、Serverless、高密度部署这些云原生场景来说,Quarkus已经是一个经过生产验证、性能领先、持续演进的选择。

开源项目推荐:https://gitee.com/dvsusan/knowledge-base-backend