spring boot项目fat jar瘦身

1、项目背景

spring cloud构建spring boot项目,精细化各项目的层次,达到下降耦合度的目的,项目间基于restful通讯。html

   在对项目打包过程当中,使用spring-boot-maven-plugin插件打包,生成的是fat jar,解压该jar包,会发现项目依赖的jar包存放于BOOT-INF下的lib文件夹中,分析多个子项目后会发现,相同的jar包占绝大多数,而后每次部署于线上环境,各系统的共同jar在服务器上实际上是重复搁置的,所以天然会想到是否有方法将共同的jar包,或是不常常改动的jar包,抽离出来,整理出单独的一份,而后由各子项目启动时使用外部加载,达到fat jar瘦身的目的。java

2、fat jar瘦身

   通过以上分析,及查阅相关资料,整理出如下步骤进行jar包瘦身:mysql

  

  1.各项目配置spring-boot-maven-plugin插件(官方文档),生成fat jar中留存的jar包spring

  

      <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <layout>ZIP</layout>
                    <!-- <excludeGroupIds>
                        org.springframework.boot,
                        org.springframework.cloud,
                        org.mybatis.spring.boot,
                        tk.mybatis,
                        mysql,
                        com.alibaba,
                        javax.persistence,
                        io.springfox,
                        org.springframework.session
                    </excludeGroupIds> -->
                    <includes>
                        <include>
                            <groupId>xx</groupId>
                            <artifactId>xx</artifactId>
                        </include>
                        <include>
                            <groupId>xx</groupId>
                            <artifactId>xx</artifactId>
                        </include>
                    </includes>
                </configuration>
            </plugin>

  如以上代码,能够使用excludeGroupIds,或者includes,或其余标签,具体看状况。sql

  2.在项目依赖jar中抽离出不想存放于fat jar的jar包。apache

  方法一(推荐):在项目pom文件中添加maven依赖插件(官方文档服务器

  

      <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.1.1</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <!-- <outputDirectory>E:/lib</outputDirectory> -->
                            <excludeGroupIds>
                                <!-- 留存于fat jar中的jar包的groupId属性值(多个,分隔)-->
                            </excludeGroupIds>
                            <overWriteSnapshots>true</overWriteSnapshots>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

  标签具体含义查看官方文档。restful

  使用maven对项目进行打包时,使用maven命令:session

  mvn clean install -Dmaven.test.skip=true -DoutputDirectory=E:/lib(-DoutputDirectory=E:/lib是命令动态指定项目依赖的jar包导出的路径,若在项目中指定了outputDirectory的标签值,则将覆盖此动态路径)mybatis

  配置插件执行此命令后,项目中除excludeGroupIds标签中配置的jar包外,其他都将导入到指定目录中,至此完成抽离fat jar中多余的jar包。

  方法二:项目中不添加maven依赖插件,直接在对项目使用mvn复制依赖jar包的命令,这种方式须要挨个对各个子项目进行依赖复制,子项目少能够使用。

  mvn dependency:copy-dependencies -DoutputDirectory=E:/lib(若无动态指定目录,默认在项目的target路径下生成dependency目录)

  将各项目导出的依赖jar包,统一放入一个文件夹中,去除重复,并删除fat jar中预留存的依赖jar包,至此完成抽离fat jar中多余的jar包。

  3.将抽离出的jar包,放置服务器某一路径下,配置项目启动脚本,进行外部加载。

  nohup java -Dloader.path="xx/lib" -jar xx.jar

  -Dloader.path即外部加载地址。

  至此瘦身完毕,能够在项目打包后的jar包看到,BOOT-INF下的lib中,仅有所需的jar包,大大减小了fat jar的大小。

  pom的配置能够通用于微服务体系中,造成统一的配置,各个项目中的jar包依赖关系视具体状况更改。

3、遇到的问题及解决办法

  

  在瘦身过程当中,并非一路顺风的,当我认为大功告成,启动项目时,发现启动失败,jar冲突。

  1.解决jar包冲突,经过mvn命令分析jar包的依赖关系,并找到冲突jar包,并统一版本。

  在eclipse中,建立新Maven Build,一开始我尝试了mvn dependency:tree,总体分析一遍jar包依赖,但并无找到问题jar包的依赖关系,接着我尝试了mvn dependency:tree -Dverbose,将全部间接的隐性的依赖也分析了一遍仍未找到问题jar包的依赖关系。

  至此,我怀疑项目中没有这个jar包,反复打包后,我看到,此问题jar包的确在项目依赖中,只是隐藏的太深。因而,只能针对单个jar包进行分析:

  mvn dependency:tree -Dverbose -Dincludes=xx:xx:xx(xx:xx:xx对应jar包的groupId:artifactId:version)

  使用Dincludes后,找到了对应jar包的依赖关系,并在项目中排除了该jar包,再次打包后项目启动成功,问题解决。

  2.打包过程当中,一些细分的子项目,并未使用spring-boot-maven-plugin插件,而是使用maven-jar-plugin直接打包成一个可运行jar,再结合了fat jar瘦身配置后发现,本来能够依赖互通的jar,如今失效了。因为fat jar瘦身后的lib中,仅剩代码常常改动的项目的jar,依赖关系在可运行jar中,并未传递,所以须要在本项目中显性依赖所需的项目的jar包,才能保证项目的完整。

相关文章
相关标签/搜索