December 23, 2022|7 min|Backend Engineering
Back to posts

Quarkus VS Spring Boot

AI Summary

Quarkus 是 Red Hat 推出的云原生 Java 框架,定位为「Supersonic Subatomic Java」。本文从 Spring Boot 开发者的视角出发,对比两者的设计理念、依赖注入机制、响应式编程支持和启动性能表现。Quarkus 通过构建时元数据处理和 GraalVM 原生镜像实现毫秒级启动和极低内存消耗,适合 Kubernetes 和 Serverless 场景;Spring Boot 则以生态丰富和社区成熟见长。两者并非替代关系,而是针对不同场景的互补选择。

TL;DR

  • Quarkus:编译时 IoC + GraalVM 原生镜像 = 毫秒启动 + 超低内存
  • Spring Boot:运行时反射 + 动态代理 = 灵活 + 启动慢(硬伤)
  • 👉 如果你的服务要跑在 K8s 里、或者做 Serverless,Quarkus 值得尝试
  • 👉 如果你追求生态丰富、文档完善、社区成熟,Spring Boot 依旧稳如老狗

Intro

Quarkus:Supersonic Subatomic Java,「超音速亚原子 Java」🚀 Cool!

👉 来自官方的介绍:专为快速启动、高吞吐量和低资源消耗而设计。

  • Container First:轻量级 Java 应用程序,最适合在容器中运行。
  • Cloud Native:Quarkus是为Kubernetes建立的,使其能够轻松部署应用程序,而无需了解该平台的所有复杂性。
  • Versatile:从小型微服务到大型单体应用。
  • Fast startup:在构建时完成更多工作,启动速度快。
  • Unify imperative and reactive:统一命令式和响应式:将非阻塞和命令式开发风格统一在一个编程模型下。
  • Standards-based:基于你常用和喜爱的标准与框架(RESTEasy and JAX-RS, Hibernate ORM and JPA, Netty, Eclipse Vert.x, Eclipse MicroProfile, Apache Camel...)

📦 All under ONE framework.

🔍 从自己熟悉的视角出发,理解 Quarkus 在解决什么问题 ?

我们知道 Spring Boot 通过自动配置,内嵌容器等方式已经非常进步的做到了开箱即用,是 Spring 生态顺应云原生趋势的进步。

Quarkus 不是 Spring Boot 的替代品,而是一个针对特定场景的补充 --> 让你的服务在云上跑得更舒服。

它解决的核心问题是:传统 Java 框架在云原生场景下太重了

  • Spring Boot:灵活、成熟、生态好,适合大多数场景
  • Quarkus:快、轻、省,适合 K8s / Serverless / 容器优先的场景

一、设计理念:两条完全不同的路

先来看个表格:

对比维度Spring BootQuarkus
核心理念「约定大于配置」,简化 Spring 开发「容器优先」,为云原生而生
设计哲学运行时灵活,依赖注入、反射、AOP 全上编译时搞定一切,运行时要快要轻
启动时间慢(秒级)极快(毫秒级,GraalVM 原生更是变态)
内存占用高(至少几百 MB)低(原生镜像可以 <100MB)
生态极其丰富相对年轻但覆盖核心场景

Spring Boot 的思路是:我给你铺好路,你随便玩。启动慢点怎么了?服务器扛得住。

Quarkus 的思路是:别废话,上来就要快。你要跑在容器里?要 K8s 调度?要 Serverless 冷启动?那就别搞那些运行时反射的老套路了。

本质区别就一句话:

Spring Boot 把能做的都留到运行时做,Quarkus 把能做的都提前到编译时做。


二、依赖注入:ArC vs Spring

这部分我之前在分析 Spring Boot @ConfigurationProperties 源码时详细聊过,有兴趣可以翻一下。

Spring 的依赖注入是运行时反射

  1. 启动时扫 classpath,找到所有 @Component / @Service
  2. 通过反射创建 bean 实例
  3. 根据 @Autowired 找到依赖关系,注入

这套流程熟悉吧?但问题在于:反射是要成本的

Quarkus 搞了个 ArC(Arc = Annotation + CDI),基于 CDI Lite 标准。核心区别在于:

  • 编译时:Quarkus 的构建工具会扫描你的代码,生成直接的依赖注入代码
  • 运行时:不再需要反射,直接调用生成好的代码

简单理解就是:Spring Boot 是「边跑边组装」,Quarkus 是「跑之前就组装好了」。

代码对比

Spring Boot:

java
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
}

Quarkus(其实一样写,但底层原理不同):

java
@Service
public class UserService {
    @Inject
    private UserRepository userRepository;
}

写法上几乎没区别,但 ArC 在编译时就把 @Inject 的目标解析好了,不再是运行时反射。


三、响应式编程:WebFlux vs Mutiny

Spring Boot 有 WebFlux,用的是 Project Reactor(Mono / Flux)。

Quarkus 也有响应式编程,用的是 Mutiny

先说个人感受:Mutiny 比 Reactor 好上手。

为什么?

Reactor 的概念有点绕:Flux 可以是 0..N 也可以是 1..N,不读几遍文档总觉得差点意思。

Mutiny 就直观多了:

  • Uni<T>:异步结果,类似于 RxJava 的 MaybeSingle,有且只有一个结果
  • Multi<T>:多个异步结果,类似于 Flux,可以有零个或多个

代码对比

Spring WebFlux:

java
@Service
public class UserService {
    public Flux<User> findAll() {
        return userRepository.findAll();
    }
}

Quarkus Mutiny:

java
@Service
public class UserService {
    public Multi<User> findAll() {
        return userRepository.findAll();
    }
}

基本一样的思路,但 Mutiny 的命名更符合直觉。

再来看一个更有意思的对比 —— 阻塞 vs 非阻塞

Spring WebFlux:

java
@GetMapping("/{id}")
public Mono<User> getUser(@PathVariable Long id) {
    return userRepository.findById(id); // 看起来像同步,但底层是非阻塞
}

Quarkus RESTEasy Reactive + Mutiny:

java
@GetMapping("/{id}")
public Uni<User> getUser(@PathVariable Long id) {
    return userRepository.findById(id);
}

两者都是非阻塞的,但 Quarkus 的区别在于:如果你不加 Uni,直接返回 User,它默认就是阻塞的。

简单说:Quarkus 对响应式的支持更「一是一二是二」,你用 Uni 就是非阻塞,用普通类型就是阻塞,没有魔法。


四、启动性能:这才是 Quarkus 的主场

说了这么多理念和写法,实际跑起来差多少?

先看一下官方给出的参考数据(不同硬件环境有差异):

指标Spring Boot (JVM)Quarkus (JVM)Quarkus (Native)
启动时间秒级亚秒级 ~1s毫秒级 <0.1s
内存占用几百 MB约 100-200MB< 50MB
JIT 预热需要需要不需要

这些数字在不同机器上会有差异,但趋势是确定的

  • Quarkus 在 JVM 模式下已经比 Spring Boot 快很多
  • Quarkus + GraalVM 原生镜像 = 开挂级别的性能

为什么快?

核心就三点:

  1. 构建时元数据处理:不需要在启动时扫 classpath、解析注解、创建反射代理
  2. 静态代码生成:把原本运行时做的事,提前到编译时做好
  3. GraalVM 原生镜像:直接编译成机器码,不需要 JVM,进一步减少内存和启动时间

五、生态对比:Spring Boot 依旧是王者

说完 Quarkus 的好,也得说点实在的。

Spring Boot 的优势:

  • 生态极其成熟:Spring Cloud、Spring Security、Spring Batch... 要啥有啥
  • 文档完善:踩的坑前人都踩过,Stack Overflow 一搜一堆
  • 社区庞大:出了问题不慌,总有人遇到过

Quarkus 的挑战:

  • 生态相对年轻:有些场景的扩展还不如 Spring 全
  • 学习曲线:虽然写法和 Spring Boot 很像,但底层原理不同,排查问题时要心里有数
  • 工具链:本地开发体验还在不断完善

Reference

Command Palette

Search for a command to run...