Load testing our robots API with Gatling
In a previous blog post we made an API with spray. Now we're going to load test it. For this, we will use http://gatling.io/#/. In a scala class we can write exactly what and how we want to run the test. In this test, we will do a post to our API and create a new robot called C3PO. We will do this 1000 times per second and keep doing this for 10 seconds. For a total of 10000 C3POs! RobotsLoadTest.scala:
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class RobotsLoadTest extends Simulation {
val baseUrl = "http://localhost:8080" //We need to have our API running here
val httpProtocol = http
.baseURL(baseUrl)
.inferHtmlResources()
.acceptEncodingHeader("gzip,deflate")
.contentTypeHeader("application/json")
.userAgentHeader("Apache-HttpClient/4.1.1 (java 1.5)")
val s = scenario("Simulation")
.exec(http("request_0")
.post("/robots")
.body(StringBody("""{
| "name": "C3PO",
| "amountOfArms": 2
|}""".stripMargin))
)
setUp(s.inject(constantUsersPerSec(1000) during(10 seconds))).protocols(httpProtocol)
}
If you want to use maven, there is a nice Gatling plugin. But of course we'd rather use gradle. This works fine too, since we can just run Gatling as a java program. build.gradle:
apply plugin: 'scala'
version = '1.0'
repositories {
mavenCentral()
}
dependencies {
ext.gatlingVersion = '2.1.7'
compile group: 'io.gatling', name: 'gatling-app', version: gatlingVersion
compile group: 'io.gatling', name: 'gatling-recorder', version: gatlingVersion
compile group: 'io.gatling.highcharts', name: 'gatling-charts-highcharts', version: gatlingVersion
}
task gatling(dependsOn: 'compileTestScala') << {
javaexec {
main = 'io.gatling.app.Gatling'
classpath = sourceSets.test.output + sourceSets.test.runtimeClasspath
args '-sf', sourceSets.test.output, //source folder
'-bf', sourceSets.test.output.classesDir, //target folder where gatling will compile the simulation
'-s', 'RobotsLoadTest', //The simulation to run
'-rf', 'build/reports/gatling' //place to put the report
}
}
We can run this test with gradle gatling
to get our results.
================================================================================
---- Global Information --------------------------------------------------------
> request count 10000 (OK=10000 KO=0 )
> min response time 0 (OK=0 KO=- )
> max response time 455 (OK=455 KO=- )
> mean response time 11 (OK=11 KO=- )
> std deviation 39 (OK=39 KO=- )
> response time 50th percentile 4 (OK=4 KO=- )
> response time 75th percentile 7 (OK=7 KO=- )
> mean requests/sec 975.515 (OK=975.515 KO=- )
---- Response Time Distribution ------------------------------------------------
> t < 800 ms 10000 (100%)
> 800 ms < t < 1200 ms 0 ( 0%)
> t > 1200 ms 0 ( 0%)
> failed 0 ( 0%)
================================================================================
Reports generated in 2s.
Please open the following file: build/reports/gatling/robotsloadtest-1438856116217/index.html
This is already a pretty neat report. Opening the html file will be even prettier. Seems like our API can handle 1000 requests/second at least fine. Going higher we'll have to take some other things into consideration.
- The amount of connection we can open at once.
- We're running both the API and gatling on the same machine now.
- If we run it on another machine, the network may become the bottleneck
- Gatling may be the bottleneck.
You can find the whole source here.