⭐ 前言
原生开发是现在比较火的一个话题,程序员更倾向于将成果打包为一个可执行的文件直接运行(有时也会打包为Docker镜像),SpringBoot语言具有良好的编码风格,但由于其打成的jar包比较大,并且在进行Docker打包时还要考虑JRE的运行环境.
为解决该问题,Oracle公司主导开发了Grallvm可以为Java提供统一运行环境,本篇文章就是记录如何将SpringBoot程序打包为可执行文件并封装为Docker镜像.
🤔 什么是Graalvm?
GraalVM 是一个高性能的跨语言虚拟机和编译器平台,由 Oracle 主导开发,旨在为多种编程语言提供统一的运行时环境,并支持将应用程序提前编译(AOT)为原生可执行文件。
🫱 具有优势:
- 启动速度快,打包为原生包后SpringBoot的启动速度在几毫秒.
- 打包成Docker镜像后体积相较于需要使用JAR包的Docker运行环境体积缩减70%
⭐ 安装Grallvm
⬇️ 下载Grallvm
需要在Graalvm官网根据系统选择合适的版本进行下载,解压到对应的目录.
编辑
这里使用JDK21包.
📄 配置Graalvm环境
配置GraalVM JDK与配置JDK环境的方式类似,这里我使用的是Linux系统(Deepin),需要在~/.bashrc文件内添加以下内容:
export GRAALVM_HOME=/home/seaua/环境配置/jdk export JAVA_HOME=$GRAALVM_HOME export PATH="$JAVA_HOME/bin:$PATH"
这里将配置系统变量JAVA_HOME,GRAALVM,PATH指向我们下载的GRAALVM JDK目录.
然后使用下述命令使环境变量生效:
source ~/.bashrc
🔢 打包顺序
打包为Jar包->编译为可执行文件->打包为Docker镜像
⭕ 开发环境
名称 | 版本 |
JDK | 21 graalvm版本 |
maven | 3.9.11 |
SpringBoot | 3.5.6 |
docker | 26.1.4 |
⭐ 程序步骤
🔷 Pom依赖
这里使用SpringBoot 3.5.6版本 ,编译版本和目标版本使用下载配置JDK21版本.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.uav</groupId> <artifactId>springboot-native</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.5.6</version> </parent> <properties> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
按照打包顺序需要添加下面两个打包工具依赖:
native-maven-plugin: 用于将jar包打包为可执行包.
spring-boot-maven-plugin: 用于将SpringBoot程序打包为Jar包.
<build> <plugins> <plugin> <groupId>org.graalvm.buildtools</groupId> <artifactId>native-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.uav.BootApplication</mainClass> </configuration> </plugin> </plugins> </build>
🔷 添加测试代码
为Web程序添加一些测试代码,以确认打包程序的运行状态.
BootApplication.java
package com.uav; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class BootApplication { public static void main(String[] args) { SpringApplication.run(BootApplication.class, args); } }
UserController.java
package com.uav; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @RequestMapping("/users") public String getUsers() { return "This is a list of users"; } }
一个简单的GET请求/users路径并返回一个字符串.
⭐ 打包步骤
🔷 打包为可执行文件
首先在命令行中运行以下命令将SpringBoot程序打包为Jar包并同时编译生成可执行文件:
mvn -Pnative native:compile
这会在target目录内生成一个jar文件的同时生成一个编译后的可执行文件.
编辑
这里的springboot-native即为打包后的可执行文件(这里如果是Windows系统会生成.exe文件).
🔷 打包为Docker镜像
在项目根目录内编写一个Dockerfile用于打包镜像,内容如下:
FROM ubuntu:jammy COPY target/springboot-native springboot-native ENTRYPOINT ["/springboot-native"]
这里使用ubuntu镜像并将打包好的可执行文件复制到镜像内部,并设置为执行入口. 保存后通过以下命令进行打包:
docker build . -- tag my-app
打包完成后使用docker images 查看打包完成的镜像.
编辑
使用以下命令运行该docker镜像:
docker run -p 8080:8080 myapp
可以看到日志打印启动仅用了0.065秒,启动速度还是非常快的.
编辑
⭐ 总结
使用Graalvm可以将程序编译为可执行文件,并且文件体积相对于(JAR包+JRE运行环境+Linux)环境的镜像体积是比较小的,更快的启动速度可以保证程序在后台更新时可以做到无感知的重启更新,在实际生产使用还是非常不错的.
如果内容对你有帮助,麻烦留一个赞👍和收藏⭐支持一下!
如果你对区块链内容感兴趣可以查看我的专栏:小试牛刀-区块链
感谢您的关注和收藏!!!!!!