微服务Jar瘦身

由于公司是微服务项目,但所有服务器又都部署在一个服务器之上。此时,默认的Spring Boot打包方式会导致每个服务的Jar中有大量重复的第三方Jar。基于这个原因,可对服务打包进行第三方Jar优化。


一、修改 pom.xml 文件

在 Application 服务的 pom.xml 文件进行修改,build.plugins 中添加如下内容:

<!--拷贝依赖到jar外面的lib目录-->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.2.0</version>
    <executions>
        <execution>
            <id>copy-dependency</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <!--输出目录-->
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <excludeTransitive>false</excludeTransitive>
                <stripVersion>false</stripVersion>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.2.0</version>
    <configuration>
        <archive>
            <!-- 生成的jar中,不要包含pom.xml和pom.properties这两个文件 -->
            <addMavenDescriptor>false</addMavenDescriptor>
            <manifest>
                <!-- 是否要把第三方jar加入到类构建路径 -->
                <addClasspath>true</addClasspath>
                <!-- 外部依赖jar包的最终位置 -->
                <classpathPrefix>lib/</classpathPrefix>
                <!-- 配置项目启动类 -->
                <mainClass>com.zbzk.mpsafe.education.start.EducationStartApplication</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

对 spring-boot-maven-plugin 组建进行修改, 主要是在 configuration 节点添加参数,修改后如下:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>2.1.5.RELEASE</version>
    <configuration>
        <layout>ZIP</layout>
        <includes>
            <include>
                <groupId>noting</groupId>
                <artifactId>noting</artifactId>
            </include>
        </includes>
        <mainClass>com.zbzk.mpsafe.education.start.EducationStartApplication</mainClass>
        <classifier>opt</classifier> <!-- 重命名可执行jar包名字,不然可被依赖jar包名字会自动修改 -->
    </configuration>
    <executions>
        <execution>
            <id>repackage</id>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

二、执行Maven打包

通过IDEA组建或者Maven命令(mvn clean install -U -DskipTests -f common/pom.xml) 对项目进行打包。打包之后 target 结构如下:

├── classes
├── geerated-sources
├── lib
├── logs
├── maven-archiver
├── maven-status
├── sysconfig-start-0.0.6-SNAPSHOT-opt.jar
└── sysconfig-start-0.0.6-SNAPSHOT.jar

以上目录中, 主要使用 lib 文件夹和 sysconfig-start-0.0.6-SNAPSHOT-opt.jar 文件。

三、打包服务并上传服务器

通过 Jenkins 自动化构建之后, 执行 Shell 对文件进行复制、打包、压缩、传输、解压。Shell 如下:

ip=192.168.11.118

## 删除服务器原打包文件
ssh root@$ip "rm -rf /opt/app/safe_dep.tar.gz"

## 删除并创建本地文件
rm -rf safe_dep.tar.gz safe_dep
mkdir -p safe_dep/lib

## Copy全服务Jar及lib
tar_list="education envpro equipment pending security sysconfig security_routine report inventory evaluation"
tar_list=`echo $tar_list |sed 's/,/ /g'`
for arg in $tar_list
do
    cp ${arg}/${arg}-start/target/lib/* safe_dep/lib
    cp ${arg}/${arg}-start/target/*-opt.jar safe_dep/
    
done

## 打包文件
tar -czvf safe_dep.tar.gz safe_dep/

## 传文件到远程服务器并解压
scp safe_dep.tar.gz root@$ip:/opt/app
ssh root@$ip "tar -zxvf /opt/app/safe_dep.tar.gz -C /opt/app"

if [[ ! -n "$server_list" ]]; then 
  server_list="education equipment pending security sysconfig security_routine report inventory evaluation"
fi
echo APP LIST $server_list
server_list=`echo $server_list |sed 's/,/ /g'`
echo $server_list
for arg in $server_list
do
    ssh root@$ip "sh /opt/app/simple.sh  $arg"
done

上述命令主要是复制 lib 和 *-opt.jar 文件到 safe_dep 文件夹,然后通过 tar 命令打包压缩,再通过 scp 远程传输到目标服务器,最后在远程目标服务器执行 Shell 解压命令。

四、启动服务

登陆解压后的目标服务器,cd 到解压目录下(cd /opt/app/safe_dep),结构如下:

├── lib
├── education-start-0.0.6-SNAPSHOT-opt.jar
├── envpro-start-0.0.6-SNAPSHOT-opt.jar
├── equipment-start-0.0.6-SNAPSHOT-opt.jar
├── evaluation-start-0.0.6-SNAPSHOT-opt.jar
├── inventory-start-0.0.6-SNAPSHOT-opt.jar
├── pending-start-0.0.6-SNAPSHOT-opt.jar
├── report-start-0.0.6-SNAPSHOT-opt.jar
├── security_routine-start-0.0.6-SNAPSHOT-opt.jar
├── security-start-0.0.6-SNAPSHOT-opt.jar
└── sysconfig-start-0.0.6-SNAPSHOT-opt.jar

执行相应的服务启动命令即可启动服务:

java -jar -Djava.ext.dirs=lib sysconfig-start-0.0.6-SNAPSHOT-opt.jar