Stress Test Your Webserver With Gatling
Steps
Create the necessary directories for gatling to operate in:
mkdir -p $HOME/gatling/conf
mkdir -p $HOME/gatling/user-files/simulations
mkdir -p $HOME/gatling/results
Create A Test Configuration
We need to create a "simulation" file for telling Gatling what we want to do in our test. E.g hit our site with 100 users at once.
Create a file at $HOME/gatling/user-files/simulations/MyBasicSimulation.scala
with the following contents.
package computerdatabase // 1
import io.gatling.core.Predef._ // 2
import io.gatling.http.Predef._
import scala.concurrent.duration._
class BasicSimulation extends Simulation
{
// get the number of users specified, falls back to 1 if not specified
val numUsers = Integer.getInteger("users", 1)
// get the URL specified
val siteUrl = System.getProperty("siteUrl");
val httpConf = http.baseUrl(siteUrl)
.inferHtmlResources()
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
.doNotTrackHeader("1")
.acceptLanguageHeader("en-US,en;q=0.5")
.acceptEncodingHeader("gzip, deflate")
.userAgentHeader("Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0")
val scn = scenario("MyBasicSimulation")
.exec(http("request_1")
.get("/"))
.pause(5)
setUp(scn.inject(atOnceUsers(numUsers))).protocols(httpConf)
}
Run The Test!
Now execute the following command after editing the siteUrl
and users
variables to be the site you wish to hit, and the number of users you wish to hit it with respectively.
docker run \
-e JAVA_OPTS="-Dusers=20 -DsiteUrl=https://www.mydomain.com/" \
-it \
--rm \
-v $HOME/gatling/conf:/opt/gatling/conf \
-v $HOME/gatling/user-files:/opt/gatling/user-files \
-v $HOME/gatling/results:/opt/gatling/results \
programster/gatling:3.9.5-bullseye
The docker container will run, and eventually ask you to enter a name for your test. Enter a name and leave it to run.
Check Out The Results
When the test finishes, you will be told that the results can be accessed at a location. Obviously this location is wrong as you need to take into account how you mounted the volumes.
It will be within your gatling/results
volume.
Double click the index.html file and view the results in your browser.
Reduce Verbose Logging Output
The default logging is very verbose, to the point where it is just annoying. I found that the easiest way to get a log level I liked was to create the gatling/conf/logback.xml configuration file with the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<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 -->
<!--<logger name="io.gatling.http.engine.response" level="DEBUG" />-->
<!-- 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>
Alternative Test
Another test you may wish to run, is adding x number of users every second for one minute. This can be done with the following simulation code:
package computerdatabase // 1
import io.gatling.core.Predef._ // 2
import io.gatling.http.Predef._
import scala.concurrent.duration._
class SpreadOverOneMinute extends Simulation
{
// get the number of users to add to the queue per second
val numUsersPerSecond: Double = System.getProperty("users").toDouble
// Get the number of seconds to add users for.
val numSeconds = Integer.getInteger("numSeconds", 1)
// get the URL specified
val siteUrl = System.getProperty("siteUrl");
val httpConf = http.baseUrl(siteUrl)
.inferHtmlResources()
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8")
.doNotTrackHeader("1")
.acceptLanguageHeader("en-US,en;q=0.5")
.acceptEncodingHeader("gzip, deflate")
.userAgentHeader("Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0")
val scn = scenario(siteUrl)
.exec(http("request_1")
.get("/"))
.pause(5)
setUp(
scn.inject(
constantUsersPerSec(numUsersPerSecond).during(numSeconds)
)
).protocols(httpConf);
}
References{#references}
- BlazeMeter - How to Run a Simple Load Test with Gatling
- Gatling Docs - Passing Parameters
- Gatling Docs - Quickstart
- Stack Overflow - Best way to stress test a website [duplicate]
- Docker Hub - denvazh/gatling
First published: 29th October 2019