Spring Boot 项目部署打包时怎么才能不包含外部依赖库


一、问题背景


Spring Boot 项目部署起来虽然已经简单很多了,但是一个运行 jar 包动辄几十上百兆,如果服务器是本地或者在内网还好,如果需要在公网环境部署,每次发布部署时都重新上传 Spring Boot 的 jar 包,因为网速的限制,也挺令人头大的。

二、解构 Spring Boot 的 jar 包


如果我们使用工具打开 Spring Boot 项目编译出来的 jar 文件,会发现占用磁盘空间的主要是外部依赖包,位于 jar 包内的 BOOT-INF/lib 路径下。

大多数情况对服务进行重新部署的时候,外部依赖库基本上都是不变的,所以这部分的上传是费时的重复操作。我们可以避免这部分不必要的重复。

三、解决办法


将外部依赖库从 Spring Boot 的 jar 包中分离出来,将外部依赖库单独上传服务器,以后每次更新部署的时候只需要上传瘦身后的 jar 文件,从此上传就是爽快的秒操作。

  • 第一步:修改 Spring Boot 项目的 pom.xml 的插件配置如下,编译出不包含外部依赖库的 jar 包:
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <includes>
            <include>
                <groupId>nothing</groupId>
                <artifactId>nothing</artifactId>
            </include>
        </includes>
    </configuration>
</plugin>

新编译出 jar 文件后,你会惊喜地发现原来动辄上百兆的文件,瞬间只有几百 K 的大小。

  • 第二步:在项目根目录下执行如下 mvn 命令,获得外部依赖包
mvn dependency:copy-dependencies -DoutputDirectory=.\target\lib -Dinclude
=runtime
  • 第三步:将外部依赖包和 Spring Boot 服务 jar 包上传服务器,在 jar 服务启动命令添加 loader.path 参数指向 外部依赖包的位置路径:
java -Dloader.path=<外部依赖包位置路径> -jar spring-boot-demo-0.0.1-SNAPSHOT.jar

当需要再次部署的时候,只需要编译打包 Spring Boot 服务 jar 包,然后上传服务器重启服务就行了,大大提高了效率。

四、一个服务器运行多个 Spring Boot 服务的情况


一般情况下,多个Spring Boot 服务的外部依赖库很多是重复的,也可以将多个 Spring Boot 服务的外部依赖库放到同一个目录位置,在编译打包 Spring Boot 项目的时候,修改 pom 文件的插件配置如下,使编译的 jar 文件中产生的 META-INF\MANIFEST.MF 文件中,包含运行时所需要加载的外部依赖库的信息,然后启动服务时,会自动按照 jar 文件中的信息加载外部依赖库:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <!-- 指定项目启动主类,一般不需要,根据实际情况指定 -->
                <!-- <mainClass>${project.main.class}</mainClass> -->
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
            </manifest>
        </archive>
    </configuration>
</plugin>

上面的示例中,外部依赖库的 lib 文件夹和可运行的服务的 jar 文件位于同一目录,这样运行 jar 文件时,跟根据 MANIFEST.MF 文件的依赖库路径信息从当前目录下的 lib 目录下加载需要的包文件,此时启动命令不需要 loader.path 参数。

【完】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章