最近在项目中遇到了一个比较奇怪的问题,在IDEA本地起项目测试的吞吐量竟然高于在服务上起jar包(源码及所有依赖的jar打包至一个jar包中)的吞吐量,服务器的内存及cpu利用率较低,这显然是不正常的,于是进行了一系列尝试,最终通过将源码与依赖的第三方jar分开解决了问题。两种打包方式效率对比如下:
方式一:源码及所有依赖的jar打包至一个jar包中
target目录结构:
Jar包目录结构:
使用java -jar xxx.jar启动jar包,jemeter测试接口吞吐量如下:
方式二:源码和依赖的jar分离
target目录结构
ZIP文件夹结构
config中是xx.jar运行需要的配置文件;lib中是xx.jar运行依赖的第三方jar
使用java -jar xx.jar启动程序,jemeter测试接口吞吐量如下:
可以看出将源码和依赖jar分离的打包方式将吞吐量提升了20多倍,打包方式不同造成吞吐量巨大差距的原因暂时还没有搞清楚,希望了解的大佬留言赐教。
附上源码和jar分离的打包方式配置:
1、使用maven assembly插件打包,配置assembly.xml
在项目 src\main\assembly\assembly.xml 路径下建立assembly.xml文件,文件的路径可以根据项目情况更改。assembly.xml文件内容如下:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<!--
必须写,否则打包时会有 assembly ID must be present and non-empty 错误
这个名字最终会追加到打包的名字的末尾,如项目的名字为 speed-api-0.0.1-SNAPSHOT,
则最终生成的包名为 speed-api-0.0.1-SNAPSHOT-bin.zip
-->
<id>bin</id>
<!-- 打包后的文件格式,可以是zip,tar,tar.gz,tar.bz2,jar,war,dir -->
<formats>
<format>zip</format>
</formats>
<!-- 压缩包下是否生成和项目名相同的根目录 -->
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<!-- 不使用项目的artifact,第三方jar不要解压,打包进zip文件的lib目录 -->
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
<fileSets>
<!-- 把项目相关的说明文件,打包进zip文件的根目录 -->
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>README*</include>
<include>LICENSE*</include>
<include>NOTICE*</include>
</includes>
</fileSet>
<!-- 把项目的配置文件,打包进zip文件的config目录 -->
<fileSet>
<directory>${project.basedir}/src/main/resources</directory>
<outputDirectory>config</outputDirectory>
</fileSet>
<!-- 把项目的脚本文件,打包进zip文件的bin目录 -->
<fileSet>
<directory>${project.basedir}/src/main/bin</directory>
<outputDirectory>bin</outputDirectory>
</fileSet>
<!-- 把项目自己编译出来的jar文件,打包进zip文件的根目录 -->
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>
2、修改pom.xml文件中关于打包的内容
<build>
<plugins>
<!-- 指定启动类,将依赖打成外部jar包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<!-- 生成的jar中,不要包含pom.xml和pom.properties这两个文件 -->
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<!-- 是否要把第三方jar放到manifest的classpath中 -->
<addClasspath>true</addClasspath>
<!-- 外部依赖jar包的最终位置 -->
<classpathPrefix>lib/</classpathPrefix>
<!-- 项目启动类 -->
<mainClass>com.xxx.xxxx.web.xxx.xxxApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- 使用assembly打包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<!-- assembly配置文件位置 -->
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- 打包发布时,跳过单元测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
3、打包jar
使用maven打包jar
打包后的工程目录如下:
config中是xx.jar运行需要的配置文件;lib中是xx.jar运行依赖的第三方jar
4、启动jar包
使用java -jar xx.jar启动即可