1.新建一个测试接口项目
里面代码非常简单,就一个hi接口:
package com.example.gatlingdemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicInteger;
@RestController
public class HelloController {
private static AtomicInteger atomicInteger=new AtomicInteger(0);
@GetMapping("/hi")
public String hi(){
System.out.println(atomicInteger.getAndIncrement());
return LocalDateTime.now().toString();
}
}
建议大家直接使用SpringBoot完成这个API,
2.新建一个Gatling测试项目
使用的jdk是1.8
1.新建Maven项目,添加依赖,最新的gatlin依赖是3.9.5, 整个pom.xml是:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.gatling.demo</groupId>
<artifactId>gatling-maven-plugin-demo-java</artifactId>
<version>3.9.5</version>
<properties>
<!-- use the following if you're compiling with JDK 8-->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- comment the 2 lines above and uncomment the line bellow if you're compiling with JDK 11 or 17 -->
<!-- <maven.compiler.release>11</maven.compiler.release>-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<gatling.version>${project.version}</gatling.version>
<gatling-maven-plugin.version>4.3.4</gatling-maven-plugin.version>
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>io.gatling.highcharts</groupId>
<artifactId>gatling-charts-highcharts</artifactId>
<version>${gatling.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven-jar-plugin.version}</version>
</plugin>
<plugin>
<groupId>io.gatling</groupId>
<artifactId>gatling-maven-plugin</artifactId>
<version>${gatling-maven-plugin.version}</version>
<configuration>
<!-- Enterprise Cloud (https://cloud.gatling.io/) configuration reference: https://gatling.io/docs/gatling/reference/current/extensions/maven_plugin/#working-with-gatling-enterprise-cloud -->
<!-- Enterprise Self-Hosted configuration reference: https://gatling.io/docs/gatling/reference/current/extensions/maven_plugin/#working-with-gatling-enterprise-self-hosted -->
</configuration>
</plugin>
</plugins>
</build>
</project>
在resource下新建配置gatling.conf文件:
#########################
# Gatling Configuration #
#########################
# This file contains all the settings configurable for Gatling with their default values
gatling {
core {
#outputDirectoryBaseName = "" # The prefix for each simulation result folder (then suffixed by the report generation timestamp)
#runDescription = "" # The description for this simulation run, displayed in each report
#encoding = "utf-8" # Encoding to use throughout Gatling for file and string manipulation
#simulationClass = "" # The FQCN of the simulation to run (when used in conjunction with noReports, the simulation for which assertions will be validated)
#elFileBodiesCacheMaxCapacity = 200 # Cache size for request body EL templates, set to 0 to disable
#rawFileBodiesCacheMaxCapacity = 200 # Cache size for request body Raw templates, set to 0 to disable
#rawFileBodiesInMemoryMaxSize = 1000 # Below this limit, raw file bodies will be cached in memory
#pebbleFileBodiesCacheMaxCapacity = 200 # Cache size for request body Peeble templates, set to 0 to disable
#feederAdaptiveLoadModeThreshold = 100 # File size threshold (in MB). Below load eagerly in memory, above use batch mode with default buffer size
#shutdownTimeout = 10000 # Milliseconds to wait for the actor system to shutdown
extract {
regex {
#cacheMaxCapacity = 200 # Cache size for the compiled regexes, set to 0 to disable caching
}
xpath {
#cacheMaxCapacity = 200 # Cache size for the compiled XPath queries, set to 0 to disable caching
}
jsonPath {
#cacheMaxCapacity = 200 # Cache size for the compiled jsonPath queries, set to 0 to disable caching
}
css {
#cacheMaxCapacity = 200 # Cache size for the compiled CSS selectors queries, set to 0 to disable caching
}
}
directory {
#simulations = user-files/simulations # Directory where simulation classes are located (for bundle packaging only)
#resources = user-files/resources # Directory where resources, such as feeder files and request bodies are located (for bundle packaging only)
#reportsOnly = "" # If set, name of report folder to look for in order to generate its report
#binaries = "" # If set, name of the folder where compiles classes are located: Defaults to GATLING_HOME/target.
#results = results # Name of the folder where all reports folder are located
}
}
socket {
#connectTimeout = 10000 # Timeout in millis for establishing a TCP socket
#tcpNoDelay = true
#soKeepAlive = false # if TCP keepalive configured at OS level should be used
#soReuseAddress = false
}
netty {
#useNativeTransport = true # if Netty native transport should be used instead of Java NIO
#allocator = "pooled" # switch to unpooled for unpooled ByteBufAllocator
#maxThreadLocalCharBufferSize = 200000 # Netty's default is 16k
}
ssl {
#useOpenSsl = true # if OpenSSL should be used instead of JSSE (only the latter can be debugged with -Djava.net.debug=ssl)
#useOpenSslFinalizers = false # if OpenSSL contexts should be freed with Finalizer or if using RefCounted is fine
#handshakeTimeout = 10000 # TLS handshake timeout in millis
#useInsecureTrustManager = true # Use an insecure TrustManager that trusts all server certificates
#enabledProtocols = [] # Array of enabled protocols for HTTPS, if empty use Netty's defaults
#enabledCipherSuites = [] # Array of enabled cipher suites for HTTPS, if empty enable all available ciphers
#sessionCacheSize = 0 # SSLSession cache size, set to 0 to use JDK's default
#sessionTimeout = 0 # SSLSession timeout in seconds, set to 0 to use JDK's default (24h)
#enableSni = true # When set to true, enable Server Name indication (SNI)
keyStore {
#type = "" # Type of SSLContext's KeyManagers store
#file = "" # Location of SSLContext's KeyManagers store
#password = "" # Password for SSLContext's KeyManagers store
#algorithm = "" # Algorithm used SSLContext's KeyManagers store
}
trustStore {
#type = "" # Type of SSLContext's TrustManagers store
#file = "" # Location of SSLContext's TrustManagers store
#password = "" # Password for SSLContext's TrustManagers store
#algorithm = "" # Algorithm used by SSLContext's TrustManagers store
}
}
charting {
#noReports = false # When set to true, don't generate HTML reports
#maxPlotPerSeries = 1000 # Number of points per graph in Gatling reports
#useGroupDurationMetric = false # Switch group timings from cumulated response time to group duration.
indicators {
#lowerBound = 800 # Lower bound for the requests' response time to track in the reports and the console summary
#higherBound = 1200 # Higher bound for the requests' response time to track in the reports and the console summary
#percentile1 = 50 # Value for the 1st percentile to track in the reports, the console summary and Graphite
#percentile2 = 75 # Value for the 2nd percentile to track in the reports, the console summary and Graphite
#percentile3 = 95 # Value for the 3rd percentile to track in the reports, the console summary and Graphite
#percentile4 = 99 # Value for the 4th percentile to track in the reports, the console summary and Graphite
}
}
http {
#fetchedCssCacheMaxCapacity = 200 # Cache size for CSS parsed content, set to 0 to disable
#fetchedHtmlCacheMaxCapacity = 200 # Cache size for HTML parsed content, set to 0 to disable
#perUserCacheMaxCapacity = 200 # Per virtual user cache size, set to 0 to disable
#warmUpUrl = "https://gatling.io" # The URL to use to warm-up the HTTP stack (blank means disabled)
#enableGA = true # Very light Google Analytics (Gatling and Java version), please support
#pooledConnectionIdleTimeout = 60000 # Timeout in millis for a connection to stay idle in the pool
#requestTimeout = 60000 # Timeout in millis for performing an HTTP request
#enableHostnameVerification = false # When set to true, enable hostname verification: SSLEngine.setHttpsEndpointIdentificationAlgorithm("HTTPS")
dns {
#queryTimeout = 5000 # Timeout in millis of each DNS query in millis
#maxQueriesPerResolve = 6 # Maximum allowed number of DNS queries for a given name resolution
}
}
jms {
#replyTimeoutScanPeriod = 1000 # scan period for timedout reply messages
}
data {
#writers = [console, file] # The list of DataWriters to which Gatling write simulation data (currently supported : console, file, graphite)
console {
#light = false # When set to true, displays a light version without detailed request stats
#writePeriod = 5 # Write interval, in seconds
}
file {
#bufferSize = 8192 # FileDataWriter's internal data buffer size, in bytes
}
leak {
#noActivityTimeout = 30 # Period, in seconds, for which Gatling may have no activity before considering a leak may be happening
}
graphite {
#light = false # only send the all* stats
#host = "localhost" # The host where the Carbon server is located
#port = 2003 # The port to which the Carbon server listens to (2003 is default for plaintext, 2004 is default for pickle)
#protocol = "tcp" # The protocol used to send data to Carbon (currently supported : "tcp", "udp")
#rootPathPrefix = "gatling" # The common prefix of all metrics sent to Graphite
#bufferSize = 8192 # Internal data buffer size, in bytes
#writePeriod = 1 # Write period, in seconds
}
}
}
配置日志文件logback-test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
</encoder>
<immediateFlush>false</immediateFlush>
</appender>
<!-- uncomment and set to DEBUG to log all failing HTTP requests -->
<!-- uncomment and set to TRACE to log all HTTP requests -->
<!--<logger name="io.gatling.http.engine.response" level="TRACE" />-->
<root level="WARN">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
新建IDEAPathHelper类:
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.util.Objects.requireNonNull;
public class IDEPathHelper {
static final Path mavenSourcesDirectory;
static final Path mavenResourcesDirectory;
static final Path mavenBinariesDirectory;
static final Path resultsDirectory;
static final Path recorderConfigFile;
static {
try {
Path projectRootDir = Paths.get(requireNonNull(IDEPathHelper.class.getResource("gatling.conf"), "Couldn't locate gatling.conf").toURI()).getParent().getParent().getParent();
Path mavenTargetDirectory = projectRootDir.resolve("target");
Path mavenSrcTestDirectory = projectRootDir.resolve("src").resolve("test");
mavenSourcesDirectory = mavenSrcTestDirectory.resolve("java");
mavenResourcesDirectory = mavenSrcTestDirectory.resolve("resources");
mavenBinariesDirectory = mavenTargetDirectory.resolve("test-classes");
resultsDirectory = mavenTargetDirectory.resolve("gatling");
recorderConfigFile = mavenResourcesDirectory.resolve("recorder.conf");
} catch (URISyntaxException e) {
throw new ExceptionInInitializerError(e);
}
}
}
新建类Recorder:
import io.gatling.recorder.GatlingRecorder;
import io.gatling.recorder.config.RecorderPropertiesBuilder;
import scala.Option;
public class Recorder {
public static void main(String[] args) {
RecorderPropertiesBuilder props = new RecorderPropertiesBuilder()
.simulationsFolder(IDEPathHelper.mavenSourcesDirectory.toString())
.resourcesFolder(IDEPathHelper.mavenResourcesDirectory.toString())
.simulationPackage("computerdatabase")
.simulationFormatJava();
GatlingRecorder.fromMap(props.build(), Option.apply(IDEPathHelper.recorderConfigFile));
}
}
新建包computerdatabase,新建类ComputerDatabaseSimulation:
package computerdatabase;
import io.gatling.javaapi.core.ChainBuilder;
import static io.gatling.javaapi.core.CoreDsl.exec;
import static io.gatling.javaapi.core.CoreDsl.rampUsers;
import static io.gatling.javaapi.core.CoreDsl.repeat;
import static io.gatling.javaapi.core.CoreDsl.scenario;
import io.gatling.javaapi.core.ScenarioBuilder;
import io.gatling.javaapi.core.Simulation;
import static io.gatling.javaapi.http.HttpDsl.http;
import static io.gatling.javaapi.http.HttpDsl.status;
import io.gatling.javaapi.http.HttpProtocolBuilder;
public class ComputerDatabaseSimulation extends Simulation {
ChainBuilder myApp =
// Note how we force the counter name, so we can reuse it
repeat(4, "i").on(
exec(
http("test Hi")
.get("/hi")
.check(status().is(200))
).pause(1)
);
HttpProtocolBuilder httpProtocol =
http.baseUrl("http://127.0.0.1:8080")
.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
.userAgentHeader("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36")
.inferHtmlResources()
.acceptEncodingHeader("gzip, deflate, br");
ScenarioBuilder keTest = scenario("test Hi").exec(myApp);
{
setUp(
keTest.injectOpen(rampUsers(2).during(10))
).protocols(httpProtocol);
}
}
注意:
1.http中的名字必须和scenario 名字一致。
2.http.baseUrl("http://127.0.0.1:8080") 必须加上前缀http或者https。
构建完成后使用命令:mvn gatling:test 进行测试。
看到下面就是运行成功了
可以查看结果了。
这是最基本的入门了,建议大家查看官方文档:
Gatling - Quickstart
本文的Maven例子来自官网:https://github.com/gatling/gatling-maven-plugin-demo-java