如何避免每次更新Spring Boot应用时上传完整.jar文件
解决Spring Boot应用增量更新的方案
针对你遇到的每次更新都要传完整大Jar的问题,这里有几个实用的解决思路,能大幅减少部署时的传输数据:
1. 分离第三方依赖与业务代码(最直接落地)
把不变的第三方依赖和你写的业务代码分开打包,第一次部署传全量,之后只传几MB的业务代码包就行。
修改你的pom.xml配置
调整spring-boot-maven-plugin,同时添加依赖复制插件:
<build> <plugins> <!-- Spring Boot打包插件,生成仅含业务代码的可执行Jar --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> <includes> <include> <groupId>groupId</groupId> <artifactId>artifact</artifactId> </include> </includes> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> <configuration> <classifier>exec</classifier> </configuration> </execution> </executions> </plugin> <!-- 把所有第三方依赖复制到单独的lib目录 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>
打包后,target目录会生成artifact-1.1.1-exec.jar(仅业务代码)和lib目录(所有依赖)。部署时:
- 第一次:把
lib目录和业务Jar传到服务器 - 后续更新:只传新的业务Jar
启动命令:
java -cp "artifact-1.1.1-exec.jar:lib/*" groupId.YourApplicationMainClass
2. 用Spring Boot分层Jar(官方推荐)
Spring Boot 2.3+支持分层Jar,自动把Jar拆成依赖层、业务代码层、资源层等,部署时只传变化的层。
配置分层Jar
修改spring-boot-maven-plugin:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> <!-- 启用分层功能 --> <layers> <enabled>true</enabled> </layers> </configuration> </plugin>
打包后,用工具拆分分层:
java -Djarmode=layertools -jar artifact-1.1.1.jar extract
会生成dependencies/、application/等目录。部署时:
- 第一次传所有目录
- 后续只传变化的
application目录
启动命令:
java -cp "dependencies/:application/" org.springframework.boot.loader.launch.JarLauncher
3. 用rsync做增量传输(零配置快速生效)
如果不想改打包配置,直接用rsync工具同步Jar,它会自动对比新旧文件的差异块,只传变化的部分:
rsync -avz target/artifact-1.1.1.jar user@your-server:/deploy-path/
这种方式简单粗暴,适合小版本迭代的场景。
4. Docker增量部署(适合容器化环境)
如果用Docker部署,利用镜像分层特性,把依赖层和业务层分开构建,每次更新只传几MB的业务层镜像:
示例Dockerfile
# 第一步:构建依赖层(会被缓存) FROM openjdk:17-jdk-slim as dependency-layer WORKDIR /app COPY target/lib/ ./lib/ # 第二步:构建业务代码层(每次更新只重建这层) FROM dependency-layer as app-layer COPY target/artifact-1.1.1-exec.jar ./ CMD ["java", "-cp", "artifact-1.1.1-exec.jar:lib/*", "groupId.YourApplicationMainClass"]
第一次构建后,依赖层会被Docker缓存,后续更新业务代码时,只需要重新构建app-layer,传输的镜像体积极小。
内容的提问来源于stack exchange,提问作者user2674471
相关产品推荐
相关产品推荐

