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 參數。

【完】

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