体验springboot服务docker打包分层

前言

随着云原生技术的发展,现在大部分企业项目都通过容器化来部署项目,不管是docker部署还是k8s都离不开打镜像的环节,传统打镜像的方式通常时间上会比较漫长,有时候改动少量代码就需要全部打包。今天来体验一下Springboot2.3.0后的分层打包功能。

普通打包

我们先新建一个添加了springboot依赖的maven测试项目,对于诸位老Javaboy来说属于闭着眼操作了,默认的maven项目里一般不会自动添加上打包插件。最开始接触springboot的时候使用maven package打出来jar包启动会发现报错找不到入口类。

所以一定要在pom中加上

xml 复制代码
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>com.uptown.sign.SignApplication</mainClass>
                <layout>ZIP</layout>
                <fork>true</fork>
                <addResources>true</addResources>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

随便写一个hello world的控制器入口,然后直接编写Dockerfile文件

bash 复制代码
FROM openjdk:8-jdk-alpine

# 打包命令
RUN mvn package
# 声明一个端口但不真正运行在这个端口
EXPOSE 8080
# 把打出来的包添加到镜像中
ADD target/*.jar ./app.jar
# 执行命令
CMD java -jar app.jar

完事之后运行命令打成镜像测试

bash 复制代码
docker build . -t test:0.0.1

打出镜像后查看镜像的分层结构。

bash 复制代码
docker inspect test:0.0.1

图中的Layers就是镜像层,docker是会按命令分层,我们把hello world改成fuck work,重新执行下上述步骤再docker inspect分析下新镜像的Layers会发现

你会发现这些Layers中只有最后一处与旧镜像内容不一样,我们仅仅只改动了一个接口返回的文案,重新打包后会把所有动作重新都做一边,做完后发现打出来的镜像每层基本都一样,只有最后一层有变化,那么我们能不能只重新制作有变化的包呢。

分层打包

当然是可以了,这就是springboot在230加的新特性,虽然现在springboot版本已经出道3了,但是我认为越迭代越重,加了很多可有可无的东西,不如老版本中一些好用的特性值得把玩。

根本原理其实是一个springboot打出jar包中主要包含四个部分,自己写的代码 ,第三方依赖 、SpringBoot内部配置 、快照依赖 ,如果仅仅只是改动了自己写的代码的话那其他那三部分根本不用变。也就是说如果你换了依赖版本那就不行了。

首先在pom中打开分层开关

xml 复制代码
<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 package打包之后我们用命令分析下jar包内容

ini 复制代码
java -Djarmode=layertools -jar target/dockers-demo-0.0.1-SNAPSHOT.jar list

这里就分别对应了上述那四个部分代码,所以如果只更改部分代码的话并不需要再将依赖相关的代码编译上次编译完的直接用呗。

ini 复制代码
FROM openjdk:8-jdk-alpine
RUN mvn package
ADD target/*.jar ./app.jar
RUN java -Djarmode=layertools -jar app.jar extract

FROM openjdk:8-jre
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/ ./

ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

改造后你再去打包会发现特别快,springboot好用就在于内置了很多依赖包,跨过依赖包单独打业务代码快的一批,但是仅在依赖版本未发生变更的场景下生效。

相关推荐
环境栈笔记38 分钟前
指纹浏览器安卓怎么用?从运行位置到功能验收,先把三种方案分清
前端·人工智能·后端·自动化
小小张说故事1 小时前
Python 的 list 为什么能装下任何类型?拆开 PyObject* 数组,以及它让你多付了多少内存
后端·python
小蒜学长2 小时前
基于SpringBoot 框架的自媒体新闻系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·mysql数据库·自媒体新闻管理系统
IT_陈寒2 小时前
JavaScript实战技巧总结:深挖数组遍历的性能陷阱与实战解法
前端·人工智能·后端
学长毕设12 小时前
基于springboot的食品仓库管理系统
java·spring boot·后端
滴滴答答哒12 小时前
ASP.NET Core + FaceRecognitionDotNet 人脸识别实战:DI 单例、特征向量持久化与 1:N 比对
后端·asp.net
captain37615 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
IT_陈寒16 小时前
Java序列化踩坑记:对象循环引用让我加班两小时
前端·人工智能·后端
泡海椒16 小时前
05-雷达图多维画像-信用评级多维画像
后端
王中阳Go16 小时前
5.27 分钟干完后端和全部测试:一场三小时笔试的五个失分点,四个不在代码上
大数据·数据库·人工智能·后端·大语言模型