Help us understand the problem. What is going on with this article?

GatlingのTips

More than 1 year has passed since last update.

Gatlingとは負荷試験ツールです。
Scalaで負荷試験のシナリオを作成でき、結果をブラウザで確認できます。
[https://gatling.io/docs/2.3/]

基本的な使い方

  • gatlingはSimulationをextendsして使います
  • setUpでは負荷試験のシナリオ(scenario)を設定します。
    • シナリオに対してinjectを使い、ユーザ数と実行時間(rampUsers(1) over(10))を設定します。
  • またsetUpprotocolsには負荷試験の対象となるURI(baseURL)とヘッダ情報(acceptHeader)などを設定します。

すでにScalaを使ったプロジェクトが存在する場合は、以下のようにpackageを使用してgatlingを追加できます。

※ sbtの設定については [https://gatling.io/docs/2.3/extensions/sbt_plugin/] をご確認ください。

// サンプル
package gatling
import io.gatling.core.Predef._
import io.gatling.http.Predef._

class Sample extends Simulation {
  val httpConf = http
    .baseURL("http://localhost:8080")
    .acceptHeader("application/json")

  val scn = scenario("sample scenario")
    .exec(http("get ok").get("/ok"))

  setUp(scn.inject(rampUsers(1) over(10)).protocols(httpConf))
}

複数URIを負荷試験の対象にする場合

以下のようにexecを増やします。

  val scn = scenario("sample scenario")
    .exec(http("GET ok").get("/ok"))
    .exec(http("POST login").post("/login"))
    .exec(http("GET me").get("/me"))

レスポンスの確認と保存

execはそれぞれ分けて定義することもできます。
また、checkを使えばレスポンスの確認(.check(status is 200))や、
保存(.check(bodyString.saveAs("getOk")))も可能です。

    val scn = scenario("sample scenario")
      .exec(getOk)

    val getOk = exec(
      http("GET ok")
        .get("/ok")
        .check(status is 200)
        .check(bodyString.saveAs("getOk"))
    )

例えば、ログイン処理が事前に必要な場合、以下のようにcheckを使いTokenを保存しておき、
以降のexecの処理で使うことができます。

httpのヘッダやFormの設定方法は下記URLをご確認ください。

    val scn = scenario("sample scenario")
      .exec(postLogin)
      .exec(getMe)

    val postLogin = exec(
      http("POST login")
        .post("/login")
        .formParam("password", "pass")
        .formParam("email", "sample@email.jp")
        .check(status is 200)
        // レスポンスが {Token: XXX} の場合、下記の方法で値を保存可能
        .check(jsonPath("$.Token").saveAs(s"token"))
        .check(bodyString.saveAs("postLogin"))
    )

    val getMe = exec(
      http("GET me")
        .get("/me")
        // postLoginで保存したtokenは ${token} で取得可能
        .headers(Map("Auth" -> s"${token}"))
        .check(status is 200)
        .check(bodyString.saveAs("getMe"))
    )

負荷試験中にAPIからレスポンスを詳細に確認したい場合は、下記のようにラムダ式を使用します。

    val scn = scenario("sample scenario")
      .exec(getOk)
      .exec { session =>
        println(session)
        session
      }

負荷試験の前後で別処理を実行する

たとえば、認証処理などを事前に済ませておいて、そのあとで負荷試験する場合、
下記のようにbeforeafterを使用できます。
注意が必要なのは、Simulation内ではsetUpを一つしか定義できません。
仮に認証の処理をbeforeに置きたい場合、setUpをつかうことはできません。
そのため、httpリクエストが必要な場合、WSやScalajなどを使う必要があります。

class Sample extends Simulation {
  val httpConf = http
    .baseURL("http://localhost:8080")
    .acceptHeader("application/json")

  val scn = scenario("sample scenario")
    .exec(http("get ok").get("/ok"))

  before {
    // 負荷試験前に処理
  }

  setUp(scn.inject(rampUsers(1) over(10)).protocols(httpConf))

  after {
    // 負荷試験後に処理
  }
}

API別に負荷試験する

sbtを使った、gatlingでの負荷試験は下記のようになります。
下記の例では全てのSimulationに対して負荷試験が行われます。

sbt "gatling:test"

API別に負荷試験したい場合、gatlingのディレクトリ下に複数のscalaのpackageを作ります。
一例ですが、application.confにbaseUrlを書いておいて、実行時に切り替えるということもできます。

gatling/src/
└── test
    ├── resources
    │   ├── dev
    │   │   └── application.conf
    │   └── local
    │       └── application.conf
    └── scala
        ├── Api1
        │   └── Sample.scala
        └── Api2
            └── Sample.scala
// gatling/src/test/resources/local/application.conf
gatling {
    baseUrl{
        Api1 = "http://localhost:8080",
        Api2 = "http://localhost:3000"
    }
}
// gatling/src/test/scala/Api1/Sample.scala
package gatling.Api1
import com.typesafe.config.ConfigFactory
import io.gatling.core.Predef._
import io.gatling.http.Predef._

class Sample extends Simulation {
  val private val conf = ConfigFactory.load()

  val httpConf = http
    // application.confからbaseUrlを取得
    .baseURL(conf.getString("gatling.baseUrl.Api1"))
    .acceptHeader("application/json")

  val scn = scenario("sample scenario")
    .exec(http("get ok").get("/ok"))

  setUp(scn.inject(rampUsers(1) over(10)).protocols(httpConf))
}

例えば、Api1のSample.scalaをlocal(http://localhost:8080)で実行したい場合は以下のようになります。
testディレクトリにapplication.confがあるので、PlayFramworkを使っている場合は-Dconfig.file=で指定する必要があります。

export JAVA_OPTS="-Dconfig.file=src/test/resources/local/application.conf"
// testOnlyをつかうとClassを指定して負荷試験ができます。
sbt "gatling:testOnly Api1.Sample"
fnaoto
フリーランスのなんでもエンジニア
https://fnaoto.github.io/home
campfirejp
国内最大の流通を誇るクラウドファンディングサービス「CAMPFIRE」の企画・開発・運営を行うスタートアップです
https://camp-fire.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away