闲聊
最近让疫情整的我心态微崩,政策天天变,也不知道能不能回去过年,这周还被迫跟疫情对了一波线。

这个圣熙八号对面吧,就是我搬砖的地方,真刺激,多亏那天老板的股票大涨去吃好的去了,这要是去里面吃KFC了,那今年就真得在京城看春晚没跑了。
好了,最近生活平淡无奇,认真搞技术吧。现在越来越多的项目都向容器化考虑,云原生k8s注定成为未来的潮流。
正好组里慢慢的从原生docker部署的方案慢慢迁移到Rancher部署,在一次技术分享里说到了Java项目打包大小的问题。
SpringBoot项目打包会包含我们自己的代码以及依赖的一些第三方jar包,一套技能打下来怎么也得100来M。所以官方在2.3.0以后支持了分层打包,这次就来试一试看是不是真的。
普通Docker打包
先随便创建个Springboot项目,如何编译成jar包以及Docker使用方式就不多BB了,可自行百度。做一个简单的Dockerfile测试。
pom配置默认打包插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>复制
写一个有手就行的Dockerfile,为了实验我重新买了个服务器,重新配环境,恶心的一批.
FROM openjdk:8
RUN mvn clean package -DskipTests
# 声明端口并没有真正运行在这个端口
EXPOSE 8080
ADD ./target/*.jar ./app.jar
CMD java -jar app.jar复制
然后直接docker build . -t docker-demo:0.2,整个项目就引入了一个spring-web,写了一个controller。

接着用docker inspect docker-demo:0.2查看镜像的分层结构。

改动一下项目重新走一遍打包,查看一下新镜像与之前做对比。
发现只有红框里一处编译与上一次不一样,也就是说我们只改动了几个字符,docker打包的时候依然给我们重新上传了springboot的全量jar包
改造
在默认的maven打包插件加入分层打包配置
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>true</enabled>
</layers>
</configuration>
</plugin>
</plugins>
</build>复制
再次进行打包分析操作mvn clean package,现在我们可以用下面命令来看分层打包编译的jar包结构 java -Djarmode=layertools -jar target/dockers-demo-0.0.1-SNAPSHOT.jar list
可以看到layertools识别出jar包内将依赖打包到不同文件夹中,接下来我们改造下原有的dockerfile。
先说下我们的适用场景,我们给前线部署之后可能会遇到一些bug修复,只会改一下部分代码,如果我们不分层打包的话,一次全量包会特别大。
所以如果只更改部分代码的话。
FROM openjdk:8 as builder
RUN mvn clean package -DskipTests
# 声明端口并没有真正运行在这个端口
EXPOSE 8080
ADD ./target/*.jar ./app.jar
RUN java -Djarmode=layertools -jar app.jar extract
FROM openjdk:8-jre
MAINTAINER ttzommed@foxmail.com
WORKDIR application
# 复制第三方依赖、SpringBoot内部配置、快照依赖
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./
EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]复制
思路就是:在配置了springboot2.3.0版本以上支持分层打包,并且dockerfile文件也改成相应的格式后,确实能达到我们预期的效果。
每次重新上传的只是我们自己写的代码,第三方依赖、SpringBoot内部配置、快照依赖 ,这些SpringBoot都为我们打包到不同的文件夹下。
依靠docker的分层特征,分次加入文件即可达到分层打包的效果。(咳咳咳,没截效果图是因为没打出来。。。不过肯定是没问题的!因为网上都这么说!)
冲冲冲!