0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GatlingでAPIの負荷テストを実施する:サンプルコードあり

Last updated at Posted at 2020-05-16

動機・背景

  • Webサービスのバックエンドで利用するAPIの負荷テストを行いたい
  • Gatlingというツールが良さそうだったので使ってみた備忘録
    • PythonベースのLocustは以前使ったことがあったので今回は別のものを

対象読者

  • 開発したAPIの負荷テストを実施したい方

検証環境

ホスト環境

  • CentOS 7.4.1708
  • Docker 18.09.3

公式?のDockerイメージの環境

  • Gatling 3.2.1 (Scala 2.12)

準備

Docker

公式?のDockerイメージを使います。

Scala

Dockerを使うのでローカル環境でScalaを用意しなくても何とかなりますが、Intellij で SCALA を始めるなどに沿って環境を準備しておくと、コードの確認等がスムーズです。

sbt-based Scala projectを作成します。

コード

csvファイルから読み込んだデータをランダムに流し込んでAPIのエンドポイントをテストするサンプルコードです。

データ

src/main/resources/data/search.csv
cookie,query
cookie 1,test
cookie 2,iPhone SE
cookie 3,wallet
cookie 4,scarf
cookie 3,banana
cookie 2,men's shoes
cookie 1,socks
cookie 5,microSD

Scalaコード

  • ビジネスプロセスごとにobject(Scalaのシングルトン)に分割しておくと見通しがよくコードの再利用もしやすくなります
  • constantUsersPerSec, rampUsersPerSec, nothingForなどのDSLを使って、定義したシナリオにユーザを注入していきます。
    • 一定数のユーザを注入したり、注入するユーザの数を徐々に増やしたり
src/main/scala/template/LoadTest.scala
package template

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._

class LoadTest extends Simulation {

  val feeder = csv("search.csv").random

  val httpProtocol = http
    .baseUrl("http://example.com")
    .acceptHeader("application/json")
    .connectionHeader("keep-alive")

  object Search1 {
    val search = feed(feeder)
      .exec(addCookie(Cookie("cookie", "${cookie}")))
      .exec(http("Search1")
        .get("/api/v1/search1")
        .queryParam("query", "${query}")
        .header("Keep-Alive", "150")
        .header("Content-Type", "application/json")
      )
  }

  object Search2 {
    val search = feed(feeder)
      .exec(addCookie(Cookie("cookie", "${cookie}")))
      .exec(http("Search2")
        .get("/api/v1/search2")
        .queryParam("query", "${query}")
        .header("Keep-Alive", "150")
        .header("Content-Type", "application/json")
      )
  }

  def run(): Unit = {
    val scenarioSearch1 = scenario("scenario Search1")
      .exec(Search1.search)
    val scenarioSearch2 = scenario("scenario Search2")
      .exec(Search2.search)

    val stepInjections = Seq(
      nothingFor(5 seconds),
      constantUsersPerSec(1) during (3 seconds),
      constantUsersPerSec(2) during (3 seconds),
      constantUsersPerSec(3) during (3 seconds),
      constantUsersPerSec(4) during (3 seconds),
      constantUsersPerSec(3) during (3 seconds),
      constantUsersPerSec(2) during (3 seconds),
      constantUsersPerSec(1) during (3 seconds)
    )

    val waveInjections = Seq(
      nothingFor(5 seconds),
      rampUsersPerSec(1) to 4 during (9 seconds),
      rampUsersPerSec(4) to 1 during (9 seconds)
    )

    setUp(
      // will be tested in parallel
      scenarioSearch1.inject(stepInjections),
      scenarioSearch2.inject(waveInjections)
    )
  }

  run()

}

実行は、こんなイメージ。
存在しないAPIなのでこのままでは動作確認できないですが...

run.sh
# !/bin/sh

if [ $# -ne 0 ]; then
  echo "No arguments accepted."
  exit 1
fi

mkdir -p "$PWD/results"

docker run -it --rm \
    -v $PWD/src/main/resources/opt/gatling/user-files/resources \
    -v $PWD/src/main/scala:/opt/gatling/user-files/simulations \
    -v $PWD/results:/opt/gatling/results \
    denvazh/gatling:3.2.1

まとめ

Scalaベースの負荷テストツールGatlingを試したので、備忘録としてサンプルコードとともに紹介しました。
負荷テストをコードとして残しておけるのは便利ですね。
チートシートがあるのはありがたいですが、そこから詳しいコード例に飛べないのが玉にキズだなと思いました。

参考・関連

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?