Hello Gatling community,
I’m facing problem with implementing my scenario using Gatling and I’m starting thinking I misunderstand some principles of load testing with Gatling. Here is some description of what I want to simulate with Gatling:
INTRO:
- In production we have cluster of ~30 servers that receive ~60k RPS. Each request contains JSON we should parse and reply with another JSON. All balancing is done using Nginx.
- Nginx is creating ~20 tcp keep-alive connections to each server
- Each server is handling ~2k RPS
So I wand to simulate prod conditions as close as possible.
What I have/use:
- Gatling 2.1.7 running on c4.xlarge with Ubuntu tuned for load testing
- Same as prod instance that should handle 2k RPS with max response time 120ms
- Gatling scenario
`
import io.gatling.core.Predef._
import io.gatling.core.check.CheckResult
import io.gatling.core.scenario.Simulation
import io.gatling.core.validation.Failure
import io.gatling.udp.Predef._
import io.gatling.udp.UdpMessage
import org.jboss.netty.handler.codec.string.{StringDecoder, StringEncoder}
import io.gatling.http.Predef._
import scala.concurrent.duration._
import load.utils.BearerTokenGenerator
import scala.util.Random
class ZettaLoadTest extends Simulation{
val Users = 10
val widthFeeder = Seq(58188555, 1234).toArray.map(r => Map(“widthValue” → r)).random
val bidRequest1 =
“”"{“device”: {“dpidsha1”: “dpid”, “dnt”: 1, “geo”: {“country”: “US”}}, “imp”: [{“banner”: {“h”: 58188555, “api”: [1],
“id”: “1”, “w”: ${widthValue}}, “id”: “1”}], “app”: {“publisher”: {“id”: “agltb3B1Yi1pbmNyAEsBS0GjZ291bnQY9Iv5FAw”},
“id”: “agltb3B1Yi1pdmNyBAsSA0FwcBjRmvkVDB”, “paid”: 0}, “id”: “country”, “user”: {“geo”: {}, “id”: “qwerty”}}“”".stripMargin
val bidderBaseUrl = “http://biddder.base.url”
val httpConfig = http
.baseURL(bidderBaseUrl)
.acceptHeader(“Content-type: application/x-www-form-urlencoded”)
.connection(“keep-alive”)
.shareConnections
val scn = scenario(“Zetta Load Test”)
.feed(widthFeeder)
.repeat(2000)
{
exec(
http(“zetta http post”)
.post(“/rtb23/nexage/bid”)
.body(StringBody(bidRequest1))
.asJSON
.check(status.in(200, 204))
)
}
setUp(
scn.inject(
atOnceUsers(Users)
).protocols(httpConfig)
)
}
`
Problem:
When I run this scenario I expect that Gatling will open 10 keep-alive connections for 10 virtual users and each user will repeat it’s scenario 2000 times using his own connection. Actual result is a bit different:
`
bid1:/home/alexandr.boiko # netstat -tulpan | grep ‘10.3.0.76’ | wc -l
199
tcp 0 0 10.3.1.121:8090 10.3.0.76:42546 TIME_WAIT -
tcp 0 0 10.3.1.121:8090 10.3.0.76:42551 TIME_WAIT -
tcp 0 0 10.3.1.121:8090 10.3.0.76:42477 TIME_WAIT -
tcp 0 0 10.3.1.121:8090 10.3.0.76:42485 TIME_WAIT -
tcp 0 0 10.3.1.121:8090 10.3.0.76:42612 TIME_WAIT -
tcp 0 0 10.3.1.121:8090 10.3.0.76:42577 TIME_WAIT -
`
I configured sysctl with net.ipv4.tcp_tw_reuse = 1 to force kernel reusing this TIME_WAIT connections but still I’m curious why I can’t get Gatling open only 10 connections and use them instead of 200 connections(200 handshakes, more CPU load, further from prod-like envo). Any help will be highly appreciated