背景:公司的项目采用的是微服务的形式部署,每个项目压缩后的包基本都很大,有的真是4、500M,每次poc在客户机器上部署传包都很慢,而且每次做功能更新时,整包替换也很慢,所以需要将项目瘦身。
手段:通过分析发现最大的就是lib文件,所以需要给lib瘦身
![](https://i-blog.csdnimg.cn/blog_migrate/1efd24f2f431b022279560362e26e1ec.png)
-
去除不必要的依赖(mvn dependency:analyze)
通过mvn dependency:analyze命令,找到每个项目中引用但是没有使用的jar
Unused declared dependencies found:
![](https://i-blog.csdnimg.cn/blog_migrate/c9f5d1f7e130cdcd088049b5345fc8f6.png)
但是这个不一定准确,有一些我们是有用到的,但是他还是会扫描出来,所以需要仔细确认。
这一步下来发现实际上并没有减少多少.... 毕竟一个项目还是很少会引用大量不必要的依赖的。
-
提取公共lib包
通过对比几个服务发现有一些jar包很大,而且多个项目都在使用,因此可以将jar包都放在一起,做一个公共的jar包这样就能减少重复的jar,可以解决每次poc在客户机器上部署传包都很慢的问题
同时将jar包与项目分离,每次项目上线很少会修改jar包,只需要上传代码部分即可,解决了每次做功能更新时,整包替换也很慢的问题
那么该怎么做呢?
-
分离lib、config、war
修改pom
我们的项目是使用war包方式打包的,同时使用自动化打包。
![](https://i-blog.csdnimg.cn/blog_migrate/b11d4dc32b8b938ccc9a9f17fa4da342.png)
![](https://i-blog.csdnimg.cn/blog_migrate/75abc2387b2e38125306e6ff353603b0.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c90d0116c61e468e71e0025d3cb7f1b2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5844a980455cf424390ec886a95c84f9.png)
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
<!-- 引用SpringBoot构建插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- <layout>WAR</layout>-->
<fork>true</fork> <!-- hot deploy -->
<includes>
<include>
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
<classifier>exec</classifier>
</configuration>
</plugin>
<!-- 引用构建原生War包插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<!--如果想要将配置外迁,下面标签去掉注释掉即可-->
<configuration>
<packagingExcludes>
<!--排除jar文件-->
WEB-INF/lib/*.jar,
<!--排除resources文件-->
WEB-INF/classes/*.xml,WEB-INF/classes/*.yml,
WEB-INF/classes/*.json,
<!--排除db文件夹-->
WEB-INF/classes/db/ ,
<!--排除证书-->
WEB-INF/classes/ssl/,
WEB-INF/classes/*.jks
</packagingExcludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.zorkdata.icube.WebApplication</mainClass>
</manifest>
</archive>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<!-- maven资源文件复制插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<nonFilteredFileExtensions>
<!-- <!– 过滤掉不需要编码的文件:后缀名为jks的文件–>-->
<!-- <nonFilteredFileExtension>jks</nonFilteredFileExtension>-->
</nonFilteredFileExtensions>
<!-- <outputDirectory>${project.build.directory}/lib</outputDirectory>-->
<outputDirectory>${project.build.directory}/config</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>banner.txt</include>
<include>static/*</include>
<include>db/migration/*/*.sql</include>
<include>bootstrap.yml</include>
<include>logback-spring.xml</include>
<include>*.json</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<encoding>UTF-8</encoding>
</configuration>
</execution>
</executions>
</plugin>
<!-- 将依赖包单独拷贝到 target/lib 下 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-lib</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<includeScope>compile</includeScope>
</configuration>
</execution>
</executions>
</plugin>
打包后
总包还是 171M
但是war包 只需要233k
![](https://i-blog.csdnimg.cn/blog_migrate/690ad4a50c27682f8b9346d12617e3b5.png)
lib包 近200M
![](https://i-blog.csdnimg.cn/blog_migrate/8afece81e4ad2fbd2d69ed8d6cbeea9e.png)
这一步已经实现了war包与lib、配置文件分离,下一步就需要在项目中指定lib
-
启动项目
指定lib的位置使用 -Djava.ext.dirs命令,但是当启动的时候就会报错
命令:java -jar -Djava.ext.dirs=/hbbdir/lib -server -Dfile.encoding=UTF-8 XXX-exec.war (XXX 项目名)
![](https://i-blog.csdnimg.cn/blog_migrate/0728397fe7870a2da1cb74225ebb6294.png)
看到这个报错有两个怀疑点:1:配置文件没加载上、2:jar包没加载上
先制定配置文件和其他文件
命令:java -jar -Djava.ext.dirs=/hbbdir/lib -Xbootclasspath/a:/hbbdir/XXX/config/ -server -Dfile.encoding=UTF-8 XXX-exec.war
再次启动还是这个报错,那么就怀疑是不是jar包没加载上去。
再尝试-Dloader.path命令,项目无法启动,更不行了。
于是就去查看-Djava.ext.dirs命令到底在做什么
百度了一下发现:
-Djava.ext.dirs命令是通过设置系统属性的方式加载jar包的,级别很高,他会覆盖掉Java本身的ext设置,java.ext.dirs指定的目录由ExtClassLoader加载器加载,如果没有通过-Djava.ext.dirs命令指定
加载的ext的lib,他会默认加载java下的/lib/文件夹中的jar以及/jre/lib/ext/下的jar。
而我这个报错刚好是和java.security相关报错,使用了加密是需要这个jar包的。
所以修改命令:java -jar -Djava.ext.dirs=/hbbdir/lib:$JAVA_HOME/lib/:$JAVA_HOME/jre/lib/ext/ -Xbootclasspath/a:/hbbdir/XXX/config/ -server -Dfile.encoding=UTF-8 XXX-exec.war ($JAVA_HOME :改成自己的java所在位置)
启动成功
![](https://i-blog.csdnimg.cn/blog_migrate/a5112e8f887186adc7f6d1596a400e86.png)
-
修改自动化脚本
![](https://i-blog.csdnimg.cn/blog_migrate/5320d90471468e34250aa06d35a13d08.png)