本文最后更新于:2024-11-18T14:20:10+08:00
SpringBoot-高效打包Images
介绍
虽然将一个Jar打包为镜像很容易,只需一个基础JRE镜像就可生成一个SpringBoot项目镜像。
但这种方式创建出的镜像过于臃肿,升级下一个版本仍需重新将Jar打包到镜像中。
我们知道Docker镜像是分层打包的,所以我们可以将一些基础内容封装到基镜像中,之后更新部分用另一层处理。
解析SpringBoot Jar
一般情况下,我们运行SpringBoot项目就是打一个Jar包并通过java -jar *.jar
指令去运行。
但其实我们还可以将Jar包解压后再运行,这样的话方便我们对项目进行热部署和分层打包。
我们来打一个样例Jar来看看里面的内容,只要一个基础的接口功能即可:
解压后是上述样子,我们可以看一下 BOOT-INF 是我们真正的项目代码、
META-INF 是一些源信息、剩下的就是SpringBoot编译出来的基础文件。
从org.springframework.boot.loader.JarLauncher
这个类中我们可以看到,它是我们程序的入口。
也就是我们通过java -jar
执行的入口。不难看出这里定义了代码与依赖的文件位置。
打开BOOT-INF
可以看到有两个*.idx
文件,classpath.idx
文件中定义了所有依赖的 lib :
可以看到这些都是我们初始创建SpringBoot项目所依赖的基础Jar。
layers.idx
文件中定义了项目的一些依赖信息:
剩下的两个文件相信都很熟悉,这里我就不在赘述。
Java提供了解压Jar包的功能,我们可以用jar -xf *.jar
来解压Jar包。
并通过java org.springframework.boot.loader.JarLauncher
的方式来运行我们的项目。
这样的运行方式,相对与Jar的运行要快上一些,当然也方便我们以后做热部署之类的功能。
当然除了上述的启动方式外,你还可以直接运行自己写好的SpringBootApplication
类来启动。
java -cp BOOT-INF/classes:BOOT-INF/lib/* com.example.qz.SpringbootQzDemoApplication
像这样。
当然用 JarLauncher 运行具有可预测的类路径顺序的好处。
Jar 包含一个 classpath.idx 文件,JarLauncher 在构建类路径时使用该文件。
分层打包Image
为了更容易创建优化的 Docker 镜像,Spring Boot 支持向 Jar 中添加层索引文件。
它提供了层列表和应包含在其中的 Jar 的部分。索引中的层列表是根据应将层添加到 Docker/OCI 映像的顺序进行排序的。
也就是之前提到的layers.idx
这个文件。
假设Dockerfile的路径为项目根路径,我们可以通过docker build .
来开始编译过程。
或者使用docker build --build-arg JAR_FILE=path/to/myapp.jar .
来编译也是可以的