为Gatling负载测试构建可执行JAR

时间:2015-01-11 23:43:11

标签: java load-testing gatling

我是Gatling(2.1.2)的新手,想要做一个小型原型项目给同事们展示。

根据quick start页面,我可以通过多种方式使用Gatling进行模拟:

  1. 将Gatling包解压缩到一个文件夹中,然后将我的模拟文件拖放到user-files / simulations文件夹中。 bin / gatling.sh将编译并运行模拟文件。
  2. 使用gatling-maven-plugin maven插件执行模拟。
  3. 使用gatling-highcharts-maven-archetype创建项目,然后运行Engine类。
  4. 我找到了那些问题

    对于1,很难为模拟类添加依赖项。我必须弄清楚需要什么罐子并将它们放到lib文件夹中。

    对于2,它需要安装maven。

    对于3,它只从IDE运行

    我只想要一个简单的可执行JAR文件,其中包含所有依赖项(我的模拟,加特林和第三方),并从任何计算机(如EC2实例)运行它。

    有没有办法实现这个目标?

    更新1:

    我尝试了方法3,但将所有项目文件从test文件夹移动到main,并使用maven-assembly-plugin构建了一个带有依赖项的jar。当我尝试运行该文件时,出现以下错误:

    Exception in thread "main" java.lang.ExceptionInInitializerError
        at Engine$.delayedEndpoint$Engine$1(Engine.scala:7)
        at Engine$delayedInit$body.apply(Engine.scala:4)
        at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
        at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
        at scala.App$$anonfun$main$1.apply(App.scala:76)
        at scala.App$$anonfun$main$1.apply(App.scala:76)
        at scala.collection.immutable.List.foreach(List.scala:381)
        at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
        at scala.App$class.main(App.scala:76)
        at Engine$.main(Engine.scala:4)
        at Engine.main(Engine.scala)
    Caused by: java.nio.file.FileSystemNotFoundException
        at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
        at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
        at java.nio.file.Paths.get(Paths.java:143)
        at io.gatling.core.util.PathHelper$.uri2path(PathHelper.scala:32)
        at IDEPathHelper$.<init>(IDEPathHelper.scala:7)
        at IDEPathHelper$.<clinit>(IDEPathHelper.scala)
        ... 11 more
    

    我想这与Gatling配置有关,但不知道出了什么问题。

6 个答案:

答案 0 :(得分:5)

我试着做类似的事情。我也不能使用Maven。我会试着记住我是怎么做到的。

1)我已经配置 maven-assembly-plugin 来生成具有以下依赖关系的单个JAR:

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
</plugin>

您需要确保生成的类路径中存在所有必需的库(gatling,scala运行时,锌编译器)。

2)检查依赖关系的范围,因为Maven默认只包含用 scope = compile 定义的类。最简单的方法可能是不使用测试依赖项。

3)创建一个启动脚本,例如的 launch.sh 即可。它应该包含这样的内容:

#!/bin/sh
USER_ARGS="-Dsomething=$1"
COMPILATION_CLASSPATH=`find -L ./target -maxdepth 1 -name "*.jar" -type f -exec printf :{} ';'`
JAVA_OPTS="-server -XX:+UseThreadPriorities -XX:ThreadPriorityPolicy=42 -Xms512M -Xmx2048M -XX:+HeapDumpOnOutOfMemoryError -XX:+AggressiveOpts -XX:+OptimizeStringConcat -XX:+UseFastAccessorMethods -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false ${JAVA_OPTS}"
java $JAVA_OPTS $USER_ARGS -cp $COMPILATION_CLASSPATH io.gatling.app.Gatling -s your.simulation.FullClassName

为了解释,我采用了自己的发射脚本来获取灵感。请注意,类路径参数定义中存在目标目录。

4)将已编译的目标目录和 launch.sh 编译到单个目录并分发(例如作为存档)。然后,您可以通过执行 ./ launch.sh

来完成方案

我知道这是不是标准解决方案,但它对我有用。希望它也会对你有所帮助。如果您有任何问题或建议需要改进,请与我们分享。

答案 1 :(得分:4)

您始终可以创建一个简单的Java类,使用Gatling.fromArgs启动Gatling。使用此设置,您可以只使用一个快乐的可执行jar。让这个类成为jar的mainClass而不是“io.gatling.app.Gatling”。此示例适用于scala模拟类“my.package.MySimulation”。

import scala.Option;
import io.gatling.app.Gatling;
import io.gatling.core.scenario.Simulation;

public class StartSimulation {

  public static void main(String[] args) {
    Gatling.fromArgs(new String[]{}, new Option<Class<Simulation>>() {

        private static final long serialVersionUID = 1L;

        @Override
        public int productArity() {
            return 0;
        }

        @Override
        public Object productElement(int arg0) {
            return null;
        }

        @SuppressWarnings("unchecked")
        @Override
        public Class<Simulation> get() {
            try {
                return (Class<Simulation>) Class.forName("my.package.MySimulation");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }

        @Override
        public boolean canEqual(Object o) {
            return false;
        }
    });
  }
}

答案 2 :(得分:3)

我认为这有点晚了,但我面临的问题与此相关,但是使用maven我使用了gradle。猜猜这个方法是一样的,第一个解决方案和我自己的东西有点混合。

首先,定义一个带有gatling依赖项的gradle构建文件和一个用来构建fatjar的任务

apply plugin: 'scala'
version 0.1

dependencies {
  compile group: 'io.gatling', name: 'gatling-test-framework', version: '2.1.7'
  compile group: 'com.typesafe.akka', name: 'akka-actor_2.11', version: '2.4.7'
  compile group: 'org.scala-lang', name: 'scala-library', version: '2.11.7'
}

repositories{
   mavenCentral()
   mavenLocal()
}


task fatJar(type: Jar) {
   manifest {
       attributes 'Implementation-Title': 'Preparing test',  
          'Implementation-Version': version,
          'Main-Class': 'io.gatling.app.Gatling'
   }
   baseName = project.name + '-all'
      from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } {
        exclude 'META-INF/MANIFEST.MF'
        exclude 'META-INF/*.SF'
        exclude 'META-INF/*.DSA'
        exclude 'META-INF/*.RSA'

   }
   with jar
}

该任务以

执行
gradle clean build fatJar

将生成一个自包含的jar,它将默认运行Gatling主类。因此,请告诉它您要运行的测试是使用标准的'-s'参数。

最后一步是创建一个脚本来运行它。我会“窃取”第一条评论的脚本并改变一下

#!/bin/sh

if [ -z "$1" ];
then
    echo "Test config tool"
    echo
    echo "Running Parameters : "
    echo
    echo " <Config file> : Test definition file. Required"
    echo
   exit 0;
 fi

USER_ARGS="-DCONFIG_FILE=$1"
JAVA_OPTS="-server -XX:+UseThreadPriorities -XX:ThreadPriorityPolicy=42 -Xms512M -Xmx2048M -XX:+HeapDumpOnOutOfMemoryError -XX:+AggressiveOpts -XX:+OptimizeStringConcat -XX:+UseFastAccessorMethods -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false ${JAVA_OPTS}"
java $JAVA_OPTS $USER_ARGS -jar test-project-all-0.1.jar -s FunctionalTestSimulation -nr

在我的情况下,我将使用不同的,易于配置的参数运行相同的测试,因此我的模拟始终是相同的。 我的所有scala文件都是通过jar中的gradle和package编译的,这意味着它们位于类路径中,更改Script变量的“FunctionalTestSimulation”名称使得脚本更容易适应更通用的内容。

猜猜制作Maven版本会很容易。

希望能帮到别人。

使用文件夹结构进行更新 请求之后将为项目添加文件夹结构的小草稿:

test-project
    |_ build.gradle
    |_ src
        |_ main
            |_ scala
            |_ resources
    |_ runSimulation.sh
    |_ configFile.conf

什么时候会提供一个链接到我的github与一个工作的。 干杯

答案 3 :(得分:1)

我有类似的问题,我将其修复如下:

Inside Gatling包中有bin/并查看gatling.sh。您会看到它只是将某些配置添加到类路径中,然后在io.gatling.app.Gatling中运行gatling-compiler-<version_number>.jar类。因此,您需要做的就是创建一个包含编译器的jar,向classpath添加配置和测试并运行io.gatling.app.Gatling。 步骤进行:

添加编译器依赖项:

<dependency>
        <groupId>io.gatling</groupId>
        <artifactId>gatling-compiler</artifactId>
        <version>${gatling.version}</version>
    </dependency

使用依赖项创建jar:

  <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.4.1</version>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <finalName>${project.build.finalName}</finalName>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

创建测试jar(这包括你的加特林测试)

 <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <executions>
                <execution>
                    <goals>
                        <goal>test-jar</goal>
                    </goals>
                    <configuration>
                        <excludes>
                            <exclude>src/test/resources/*</exclude>
                        </excludes>
                        <finalName>${project.build.finalName}</finalName>
                    </configuration>
                </execution>
            </executions>
        </plugin>

从您的配置中创建一个包。您可以使用maven程序集。我通常做的是创建一个单独的模块来处理为不同环境创建包。此程序包包含您的gatling.conflogback.xml以及您应用程序所需的所有其他资源,包括测试数据。 现在你基本上有三个包:application.jarapplication-tests.jarapplication-conf.zip。 在同一文件夹中解压缩application-conf.zip,复制application.jarapplication-tests.jar

在此文件夹中,您需要创建target/test-classes/文件夹 把它留空。在我的情况下,它是必需的。我想你可以怎么样 改变gatling.conf中的内容。但我不确定如何。

运行

java -cp ".:application-test.jar:application.jar" io.gatling.app.Gatling  

答案 4 :(得分:0)

我使用IntelliJ Idea,右键单击scala文件夹&gt;修复此问题。将目录标记为&gt;测试源根。现在执行&#34;引擎&#34;你会好的!

答案 5 :(得分:0)

我最近在博客上写了这个Creating a versionable, self-contained (fat-/uber-) JAR for Gatling tests,其来源可在jamietanna/fat-gatling-jar中找到。

对于Maven项目,步骤如下。

您需要做的主要事情是添加对gatling-charts-highcharts的依赖关系:

<project>
    <!-- ... -->
    <dependencies>
        <dependency>
            <groupId>io.gatling.highcharts</groupId>
            <artifactId>gatling-charts-highcharts</artifactId>
            <version>${gatling.version}</version>
        </dependency>
    </dependencies>
</project>

下一步,您需要确保您的加特林场景/模拟位于src/main中,而不是src/test中。

最后,您可以使用maven-shade-plugin来构建可执行文件JAR,该文件将Gatling的CLI运行器用作mainClass

<project>
    <!-- ... -->
    <build>
        <plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-shade-plugin</artifactId>
              <version>3.1.1</version>
              <configuration>
                <filters>
                  <!-- https://stackoverflow.com/a/6743609 -->
                  <filter>
                    <artifact>*:*</artifact>
                    <excludes>
                      <exclude>META-INF/*.DSA</exclude>
                      <exclude>META-INF/*.SF</exclude>
                      <exclude>META-INF/*.RSA</exclude>
                    </excludes>
                  </filter>
                </filters>
              </configuration>
              <executions>
                <execution>
                  <phase>package</phase>
                  <goals>
                    <goal>shade</goal>
                  </goals>
                  <configuration>
                    <transformers>
                      <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>io.gatling.app.Gatling</mainClass>
                      </transformer>
                    </transformers>
                  </configuration>
                </execution>
              </executions>
            </plugin>
        </plugins>
    </build>
</project>