【quarkus系列】构建可执行文件native image
目录
- 序言
- 为什么选择 Quarkus Native Image?
- 性能优势
- 便捷的云原生部署
- 搭建项目
- 构建可执行文件
- 方式一:配置GraalVM
- 方式二:容器运行
- 错误示例
- 构建过程分析
- 创建docker镜像
- 基于可执行文件命令式构建
- 基于dockerfile构建
- 方式一:构建micro base image
- 方式二:构建minimal base image
- 方式三:使用dockerfile多阶段构建
序言
为什么选择 Quarkus Native Image?
性能优势
- 快速启动时间
传统的 Java 应用运行在 JVM(Java Virtual Machine)上,启动时需要进行类加载、字节码解释和 JIT(Just-In-Time)编译等一系列过程,这些过程会导致启动时间较长。而 Quarkus 的 Native Image 使用 GraalVM 进行本地编译,直接将 Java 应用编译成机器码。这样,在应用启动时,几乎不需要任何额外的初始化步骤,启动时间可以快一个数量级。
例如,传统的 Java 应用可能需要几秒钟甚至更长时间才能完全启动,而使用 Quarkus Native Image 的应用通常在几十毫秒内即可启动。这对于需要快速响应和弹性扩展的场景(如微服务架构和无服务器架构)尤为重要。 - 低内存占用
由于 Quarkus Native Image 在编译时进行了一系列优化,包括去除未使用的代码和优化内存布局,生成的本地二进制文件的内存占用显著减少。这种优化不仅减少了运行时的内存消耗,还降低了垃圾回收的频率和开销。
对于在云环境中运行的应用,这种内存占用的减少意味着可以在相同的硬件资源上运行更多的实例,提升了资源利用率和性价比。
便捷的云原生部署
- 轻量级容器
传统的 Java 应用在容器化部署时,需要包含完整的 JVM 环境,这会增加容器镜像的大小。而 Quarkus Native Image 生成的二进制文件不依赖 JVM,可以显著减小容器镜像的体积。例如,一个传统的 Java 应用的容器镜像可能有几百 MB,而使用 Quarkus Native Image 的镜像可能只有几十 MB。
这种轻量级容器的优势在于:
1、更快的镜像拉取:在部署和扩展应用时,镜像的拉取速度更快,减少了启动时间。
2、更低的存储成本:减小了存储镜像所需的空间,节省了存储成本。
- Kubernetes 集成
Quarkus 天生为 Kubernetes 设计,提供了很多开箱即用的特性,简化了在 Kubernetes 环境中的部署和管理。例如:
1、自动生成 Kubernetes 资源配置:通过 Quarkus 的扩展,可以自动生成 Deployment、Service 等 Kubernetes 资源配置,减少了手动配置的工作量。
2、与 Kubernetes 原生工具集成:Quarkus 提供了与 Kubernetes 原生工具(如 Helm 和 OpenShift)的集成,方便应用的打包、部署和管理。
3、健康检查和监控:Quarkus 提供了内置的健康检查、指标收集和分布式跟踪支持,方便在 Kubernetes 环境中进行应用的监控和管理。
搭建项目
之前的文章,按照官网指南构建第一个quarkus项目,并启动运行。
【quarkus系列】创建quarkus第一个应用程序
这篇文章,我们开始学习如何本地构建quarkus可执行文件。
官网指南中,本地开发环境需要满足以下条件:
1、按照JDK17+版本;
2、本地有docker环境;
接着上篇文章中的开发代码继续开发:
关于构建成native本地文件核心配置pom.xml
<profiles><profile><id>native</id><activation><property><name>native</name></property></activation><properties><skipITs>false</skipITs><quarkus.native.enabled>true</quarkus.native.enabled></properties></profile>
</profiles>
默认构建会执行native文件;
其次或者使用命令行 -Dquarkus.native.enabled=true 作为属性传递
构建可执行文件
官网指南给出多种构建方式,优先介绍常用的方式:
方式一:配置GraalVM
方式一:(推荐使用方式二)
安装并配置GraalVM,官网链接https://quarkus.io/guides/building-native-image#configuring-graalvm
如图:

- 运行命令
./mvnw install -Dnative
如果使用该命令,没有配置GraalVM,执行报错如下:
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal io.quarkus.platform:quarkus-maven-plugin:2.13.3.Final:build (default) on project getting-started: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[ERROR] [error]: Build step io.quarkus.deployment.pkg.steps.NativeImageBuildStep#build threw an exception: java.lang.RuntimeException: Cannot find the `native-image` in the GRAALVM_HOME, JAVA_HOME and System PATH. Install it using `gu install native-image`
[ERROR] at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.getNativeImageBuildRunner(NativeImageBuildStep.java:314)
[ERROR] at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.build(NativeImageBuildStep.java:212)
[ERROR] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
[ERROR] at java.base/java.lang.reflect.Method.invoke(Method.java:580)
[ERROR] at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:909)
[ERROR] at io.quarkus.builder.BuildContext.run(BuildContext.java:281)
[ERROR] at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
[ERROR] at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
[ERROR] at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
[ERROR] at java.base/java.lang.Thread.run(Thread.java:1583)
方式二:容器运行
相对于方式一,更推荐使用方式二开发,无需配置以上环境变量,直接启动docker即可;
必要条件,确保有一个有效的容器运行时(Docker、podman)环境
首先将本地服务器docker启动;
- 构建可执行命令:
./mvnw install -Dnative -DskipTests -Dquarkus.native.container-build=true
- 显示选择运行时容器
官方也可以显式选择容器运行,命令如下:
此处我们仍然选择使用docker
./mvnw install -Dnative -Dquarkus.native.container-build=true -Dquarkus.native.container-runtime=docker
- 优化构建命令
使用命令构建不方便,也可以将其设置在application.properties
quarkus.native.container-build=true
运行命令:./mvnw install -Dnative -DskipTests即可
错误示例
如果docker未启动,则报错如图:

日志中很明显,提示需要运行docker
构建过程分析
- docker启动之后,开始pull image ,如图:

- docker同时会启动构建native镜像的容器,如图:

- 构建完成之后,本地项目会生成可执行文件,如图:

创建docker镜像
基于可执行文件命令式构建
构建命令
./mvnw package -Dnative -Dquarkus.native.container-build=true -Dquarkus.container-image.build=true
控制台日志:
Finished generating 'getting-started-1.0.0-SNAPSHOT-runner' in 3m 14s.
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildRunner] docker run --env LANG=C --rm -v /quarkus-projects/getting-started/target/getting-started-1.0.0-SNAPSHOT-native-image-source-jar:/project:z --entrypoint /bin/bash quay.io/quarkus/ubi-quarkus-native-image:22.2-java17 -c objcopy --strip-debug getting-started-1.0.0-SNAPSHOT-runner
[INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 218135ms
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 03:43 min
[INFO] Finished at: 2024-05-13T18:47:06+08:00
[INFO] ------------------------------------------------------------------------
从控制台中可以看到,已经完成docker镜像的创建以及镜像标签:22.2-java17
输入docker images查看镜像是否生成

基于dockerfile构建
方式一:构建micro base image
Micro base image 通常是指极度精简的基础镜像,这类镜像仅包含运行应用所需的最基本的依赖和工具,去除了所有不必要的部分。
特点:
1、极小的体积:micro base image 的目标是将镜像体积降到最低,以便快速传输和启动。
2、最小依赖:只包含运行应用所需的最基本的库和工具,通常没有包管理器、shell 等组件。
3、安全性:由于镜像内的组件极少,减少了攻击面,提高了安全性。
4、性能:更小的镜像体积和更少的组件有助于快速启动和高效运行。
路径src/main/docker,文件名Dockerfile.native-micro
内容如下:
FROM quay.io/quarkus/quarkus-micro-image:2.0
WORKDIR /work/
COPY target/*-runner /work/application
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
与命令同理,一样需要依赖本机的可执行文件,故不能删除可执行文件
可以使用以下命令生成 docker 映像:
docker build -f src/main/docker/Dockerfile.native-micro -t quarkus-quickstart/getting-started .
运行镜像命令
docker run -i --rm -p 8080:8080 quarkus-quickstart/getting-started
方式二:构建minimal base image
Minimal base image 通常指的是精简但仍保留了一些基础工具和库的镜像,这类镜像比 micro base image 体积稍大,但更易用。
特点
1、较小的体积:相比完整的操作系统镜像,minimal base image 体积较小,但比 micro base image 略大。
2、基本工具和库:包含一些常用的工具和库,如包管理器、shell、调试工具等,方便开发和调试。
3、较高的灵活性:在保持精简的同时,提供了一定的灵活性和便利性,适合大多数应用场景。
4、易用性:提供了更多的基础设施支持,易于使用和配置。
路径:src/main/docker,文件名Dockerfile.native
内容如下:
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9
WORKDIR /work/
RUN chown 1001 /work \&& chmod "g+rwX" /work \&& chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/applicationEXPOSE 8080
USER 1001CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
以上两种方式,均需要本地生成native可执行文件,故如果本地可执行文件删除,则需要先执行命令:./mvnw install -Dnative -DskipTests
方式三:使用dockerfile多阶段构建
使用dockerfile直接在容器中生成本机可执行文件,同时完成镜像的构建;
第一阶段使用 Maven 或 Gradle 构建本机可执行文件;
第二阶段是复制生成的本机可执行文件的最小映像;
Dockerfile
## Stage 1 : build with maven builder image with native capabilities
FROM quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-21 AS build
COPY --chown=quarkus:quarkus mvnw /code/mvnw
COPY --chown=quarkus:quarkus .mvn /code/.mvn
COPY --chown=quarkus:quarkus pom.xml /code/
USER quarkus
WORKDIR /code
RUN ./mvnw -B org.apache.maven.plugins:maven-dependency-plugin:3.1.2:go-offline
COPY src /code/src
RUN ./mvnw package -Dnative## Stage 2 : create the docker final image
FROM quay.io/quarkus/quarkus-micro-image:2.0
WORKDIR /work/
COPY --from=build /code/target/*-runner /work/application# set up permissions for user `1001`
RUN chmod 775 /work /work/application \&& chown -R 1001 /work \&& chmod -R "g+rwX" /work \&& chown -R 1001:root /workEXPOSE 8080
USER 1001CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
同理将dockerfile文件,路径src/main/docker/Dockerfile.multistage.
构建镜像命令
docker build -f src/main/docker/Dockerfile.multistage -t quarkus-quickstart/getting-started .
运行命令
docker run -i --rm -p 8080:8080 quarkus-quickstart/getting-started
相关文章:
【quarkus系列】构建可执行文件native image
目录 序言为什么选择 Quarkus Native Image?性能优势便捷的云原生部署 搭建项目构建可执行文件方式一:配置GraalVM方式二:容器运行错误示例构建过程分析 创建docker镜像基于可执行文件命令式构建基于dockerfile构建方式一:构建mic…...
linux(ubuntu)常用的代理设置
1. git代理设置与取消 # 设置 git config --global http.proxy socks5://127.0.0.1:1234 git config --global https.proxy socks5://127.0.0.1:1234 # 取消 git config --global --unset http.proxy git config --global --unset https.proxy2. conda代理设置与取消 在.cond…...
红队攻防渗透技术实战流程:红队目标上线之Webshell免杀对抗
红队攻防免杀实战 1. 红队目标上线-Webshell免杀-基础准备2. 红队目标上线-Webshell免杀-基础内容3.红队目标上线-Webshell免杀-建立认知3.红队目标上线-Webshell免杀-测试实验3.1 查杀对象-Webshell&C2后门&工具&钓鱼3.2 免杀对象-Webshell&表面代码&行为…...
Habicht定理中有关子结式命题3.4.6的证明
个人认为红色区域有问题,因为 deg ( ϕ ( S j ) ) r \deg{\left( \phi\left( S_{j} \right) \right) r} deg(ϕ(Sj))r,当 i ≥ r i \geq r i≥r时, s u b r e s i ( ϕ ( S j 1 ) , ϕ ( S j ) ) subres_{i}\left( \phi(S_{j 1}),\p…...
【Unity AR开发插件】如何快速地开发可热更的AR应用
预告 本专栏将介绍如何使用这个支持热更的AR开发插件,快速地开发AR应用。 Unity AR开发插件使用教程 更新 二、使用插件一键安装HybridCLR和ARCore 三、配置带HybridCLR的ARCore开发环境 四、制作热更数据-AR图片识别场景...
Divisibility Part1(整除理论1)
Divisibility Part1 学习本节的基础:任意个整数之间进行加、减、乘的混合运算之后的结果仍然是整数。之后将不申明地承认这句话的正确性并加以运用。 用一个不为 0 0 0的数去除另一个数所得的商却不一定是整数( a a a除 b b b,写作 b a \frac…...
代码随想录算法训练营第三十七天 | 860.柠檬水找零、406.根据身高重建队列、452.用最少数量的箭引爆气球
目录 860.柠檬水找零 思路 代码 406.根据身高重建队列 思路 代码 452. 用最少数量的箭引爆气球 思路 代码 860.柠檬水找零 本题看上好像挺难,其实挺简单的,大家先尝试自己做一做。 代码随想录 思路 这题还有什么难不难的,这道题不是非…...
GolangFoundation
GolangFoundation 一. Hello World1.1 SDK1.2 环境1.3 hello world1.4 语法规则二. 程序结构2.1 循环2.2 概述2.3 完整写法2.4 类似while2.5 死循环2.6 特殊循环三. 变量3.1 命名3.2 声明2.3 变量...
如果任务过多,队列积压怎么处理?
如果任务过多,队列积压怎么处理? 1、内存队列满了应该怎么办2、问题要治本——发短信导致吞吐量降低的问题不能忽略!!3、多路复用IO模型的核心组件简介1、内存队列满了应该怎么办 如图: 大家可以看到,虽然现在发短信和广告投递,彼此之间的执行效率不受彼此影响,但是请…...
FTP协议——BFTPD基本操作(Ubuntu+Win)
1、描述 本机(Win10)与虚拟机(Ubuntu22.04.4)上的BFTPD服务器建立FTP连接,执行一些基本操作。BFTPD安装教程:FTP协议——BFTPD安装(Linux)-CSDN博客 2、 步骤 启动BFTPD。启动文件…...
为什么需要分布式 ID?
目录 为什么需要分布式 ID 分布式 ID 的生成方法 分布式 ID 的应用场景 小结 在现代软件架构中,分布式系统架构变得越来越流行。在这些系统中,由于组件分散在不同的服务器、数据中心甚至不同的地理位置,因此要构建高性能、可扩展的应用系…...
MIT6.828 Lab2-3 Sysinfo
目录 一、实验内容二、实验过程2.1 已有的代码2.2 需补充内容/kernel/kalloc.c修改(剩余内存计算的函数)/kernel/proc.c修改(统计进程数量的函数)/kernel/defs.h修改添加/kernel/sysinfo.c文件/kernel/syscall.h修改/kernel/sysca…...
形态学操作:腐蚀、膨胀、开闭运算、顶帽底帽变换、形态学梯度区别与联系
一、总述相关概念 二、相关问题 1.形态学操作中的腐蚀和膨胀对图像有哪些影响? 形态学操作中的腐蚀和膨胀是两种常见的图像处理技术,它们通过对图像进行局部区域的像素值替换来实现对图像形状的修改。 腐蚀操作通常用于去除图像中的噪声和细小的细节&a…...
StringBufferInputStream类,你学会了吗?
在Java编程中,处理字符串数据流是一项常见的任务。 为了更灵活地处理字符串数据流,Java提供了StringBufferInputStream类,它允许将字符串转换为输入流,从而可以像处理其他输入流一样对字符串进行操作。 本文将深入探讨StringBufferInputStream类的背景、用法、优缺点以及…...
06_Tomcat
文章目录 Tomcat1.概念2.Tomcat安装3.Tomcat项目结构4.标准web项目结构5.Tomcat部署项目方式6.IDEA关联Tomcat6.1 构建tomcat和idea关联6.2 使用idea创建一个Javaweb工程6.3 使用idea将工程**构建**成一个app6.4 使用idea将构建好的app**部署**到tomcat中 Tomcat 1.概念 Tomc…...
系统安全扫描扫出了:可能存在 CSRF 攻击怎么办
公司的H5在软件安全测试中被检查出可能存在 CSRF 攻击,网上找了一堆解决方法,最后用这种方式解决了。 1、问题描述 CSRF 是 Cross Site Request Forgery的缩写(也缩写为也就是在用户会话下对某个 CGI 做一些 GET/POST 的事,RIVTSTCNNARGO一这…...
Android ART 虚拟机简析
源码基于:Android U 1. prop 名称选项名称heap 变量名称功能 dalvik.vm.heapstartsize MemoryInitialSize initial_heap_size_ 虚拟机在启动时,向系统申请的起始内存 dalvik.vm.heapgrowthlimit HeapGrowthLimit growth_limit_ 应用可使用的 max…...
Android低代码开发 - MenuPanel的源码剖析和基本使用
看了我上篇文章Android低代码开发 - 像启蒙和乐高玩具一样的MenuPanel 之后,本篇开始讲解代码。 源代码剖析 首先从MenuPanelItemRoot讲起。 package dora.widget.panelinterface MenuPanelItemRoot {/*** 菜单的标题。** return*/var title: String?fun hasTit…...
Leetcode刷题笔记3
18. 四数之和 18. 四数之和 - 力扣(LeetCode) 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应&…...
初识C语言——第二十九天
数组 本章重点 1.一维数组的创建和初始化 数组的创建 注意事项: 1.一维由低数组在内存中是连续存放的! 2.随着数组下标的增长,地址是由低到高变化的 2.二维数组的创建和初始化 注意事项: 1.二维数组在内存中也是连续存放的&am…...
如何建立有利于SEO的网站内容体系_网站 SEO 优化的周期是多长时间
如何建立有利于SEO的网站内容体系 在当今的数字时代,建立一个有利于SEO(搜索引擎优化)的网站内容体系是任何企业或个人在网络上获得成功的关键。一个优化良好的网站不仅能吸引更多的访问者,还能提升品牌的知名度和销售转化率。如…...
G-Helper深度解析:轻量级华硕性能控制替代方案革新实践指南
G-Helper深度解析:轻量级华硕性能控制替代方案革新实践指南 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Stri…...
FPGA新手避坑指南:UART、SPI、I2C三大串行协议到底怎么选?
FPGA新手避坑指南:UART、SPI、I2C三大串行协议到底怎么选? 第一次接触FPGA开发时,面对琳琅满目的通信协议选择,很多新手都会感到无从下手。UART、SPI、I2C这三种最常见的串行协议各有特点,但选错协议可能导致项目延期、…...
PPSSPP模拟器:这款安卓psp模拟器如何让你在手机上畅玩PSP经典游戏
还记得小时候躲在被窝里玩《怪物猎人》《战神》《最终幻想》的日子吗?那台黑白相间的PSP掌机承载了无数人的青春回忆。如今,PSP早已停产,但那些经典游戏并没有消失——只要你有PPSSPP模拟器,就能在手机、电脑甚至平板上重新体验它…...
MAI-UI-8B应用场景解析:如何用AI自动分析软件界面与操作流程
MAI-UI-8B应用场景解析:如何用AI自动分析软件界面与操作流程 1. 理解MAI-UI-8B的核心能力 MAI-UI-8B是一款专为图形用户界面(GUI)分析而设计的AI模型。它能够像人类一样"看"懂软件界面,理解各种UI元素的功能,并预测用户可能的操作…...
新手必看:如何用OpenSCAP快速搞定Linux服务器安全基线检查(附CentOS实战)
从零到精通的OpenSCAP实战:CentOS安全基线检查全流程拆解 刚接手服务器运维的新手常会遇到这样的困惑:明明系统运行正常,安全团队却总说存在"配置风险"。去年我们团队就发生过一起因SSH弱加密算法导致的入侵事件——攻击者仅用2小时…...
PyTorch 2.9镜像使用指南:Jupyter与SSH两种方式详细解析
PyTorch 2.9镜像使用指南:Jupyter与SSH两种方式详细解析 1. 镜像概述 PyTorch 2.9镜像是一个开箱即用的深度学习开发环境,预装了PyTorch 2.9框架和CUDA工具包。这个镜像特别适合需要快速搭建GPU加速开发环境的用户,无论是进行模型训练、推理…...
突破语言壁垒:双字节字符支持的创新解决方案——零基础也能掌握的《十字军之王II》本地化增强工具
突破语言壁垒:双字节字符支持的创新解决方案——零基础也能掌握的《十字军之王II》本地化增强工具 【免费下载链接】CK2dll Crusader Kings II double byte patch /production : 3.3.4 /dev : 3.3.4 项目地址: https://gitcode.com/gh_mirrors/ck/CK2dll 你是…...
基于STM32LXXX的数字电位器(MCP41010T-I/SN)驱动应用程序设计
一、简介:MCP41010T-I/SN 是 Microchip 公司推出的一款单通道、8位数字电位器,采用 SPI 串行接口进行通信。该器件将传统的机械电位器功能数字化,通过简单的数字指令精确调节电阻值,特别适用于需要软件控制电路参数的嵌入式系统。…...
OpenClaw多模型切换:SecGPT-14B与Qwen在安全场景的对比调用
OpenClaw多模型切换:SecGPT-14B与Qwen在安全场景的对比调用 1. 为什么需要多模型切换? 去年我在搭建个人安全分析工作流时,发现单一模型很难满足所有需求。SecGPT-14B在漏洞深度分析时表现出色,但简单的日志筛查任务用Qwen就能快…...
