gatlingで負荷試験を実施する方法

これはアソビュー Advent Calendar 2019の15日目です。

こんにちは、アソビューでBEエンジニアのThang(タン)です。
Gatlingで負荷試験を試したので備忘録です。

今回試したのは Reserve with Google APIの負荷試験です。
APIインタフェースはこちらでご参照して頂けます。

Gatlingとは

  • scalaベースの負荷試験ツールの一種です
  • 特徴:
    • テストシナリオが Scalaで書ける
    • テスト結果はhtmlで出力され、出力結果がキレイ
    • Scala知識が低くても意外と簡単に書ける

Gatling インストール

JDKが必要なので、インストールします。

$ brew install java

公式HPからzipファイルをダウンロードします。
私はバージョン 2.3.1で試しました。

Gatling 使い方

とりあえず bin にgatling.shがあるので実行して、サンプルの負荷試験を実施してみます。

$ bin/gatling.sh 

シナリオを選択します。1のAdvancedSimulationStep01を選択してみましょう。 f:id:dqth:20191215131913p:plain

実行が始まります。 f:id:dqth:20191215132015p:plain

実行完了され、結果が出力されます。
結果はこんな感じです。 f:id:dqth:20191215132106p:plain f:id:dqth:20191215132129p:plain

シナリオを書いてみる

gatlingはシナリオ自動生成機能を使っても良いのですが、今回は自分で1からシナリオを作成してみます。

シナリオの置き場所はデフォルトで user-files/simulationsになります。
ちなみに、置き場所は conf/gatling.confdirectory.simulations項目で変えられます。

書いたシナリオはこんな感じです。

class RecordedSimulation extends Simulation {

    val httpProtocol = http
        .baseURL("http://localhost:8080")
        .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
        .acceptEncodingHeader("gzip, deflate")
        .acceptLanguageHeader("ja,en-US;q=0.7,en;q=0.3")
        .doNotTrackHeader("1")
        .userAgentHeader("Mozilla/5.0 (iPhone; CPU iPhone OS 10_2_1 like Mac OS X) AppleWebKit/602.4.6 (KHTML, like Gecko) Version/10.0 Mobile/14D27 Safari/602.1")

    val order_feeder = csv("order.csv").queue

    val scn = scenario("RecordedSimulation")
        .feed(order_feeder)
        .exec(http("order_fulfillability")
            .post("/v3/CheckOrderFulfillability")
            .body(StringBody("""{"merchant_id":"${merchantId}","item":[{"service_id":"${serviceId}","start_sec":${startSec},"duration_sec":${durationSec},"tickets":[{"ticket_id":"${ticketId}","count":${count}}],"price":{"price_micros":${price},"currency_code":"JPY"}}]}"""))
        )

    setUp(scn.inject(constantUsersPerSec(1) during(5 seconds))).protocols(httpProtocol)

このシナリオは /v3/CheckOrderFulfillability APIに1秒に一回 postリクエストを送ります
リクエストbodyはStringBodyを使って設定します。
bodyのパラメータは CSVファイルのデータを使って設定します。
API IFはこんな感じです。

{
    "merchant_id": String,
    "item": [
        {
            "service_id": String,
            "start_sec": long,
            "duration_sec": long,
            "tickets": [
                {
                    "ticket_id": String,
                    "count": int
                }
            ],
            "price": {
                "price_micros": long,
                "currency_code": String
            }
        }
    ]
}

CSVファイルはこんな感じです。 ファイルの置き場所はuser-files/dataになります。

merchantId,serviceId,startSec,durationSec,ticketId,count,price
149990,service0000001,1569805200,36000,0001,2,3200000000
149990,service0000002,1569805200,36000,0002,2,3200000000
149990,service0000003,1569805200,36000,0003,2,3200000000
149990,service0000004,1569805200,36000,0004,2,3200000000
149990,service0000005,1569805200,36000,0005,2,3200000000

gatling.shを実行すると、シナリオ選択のところで今回書いたシナリオ(test)が追加されます。
それを選択すると、追加シナリオを実行できます。 f:id:dqth:20191215132458p:plain