Gatlingで負荷試験をする

負荷試験ツールGatlingのインストールからQuick Startまでを解説します。
2018.07.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

WebサイトやAPIの負荷試験を行う際にまず思い浮かぶツールはJMeterでしょう。
それ以外にGatlingというツールがあり、今回はこれを試してみました。

環境構築

GatlingはJDK8で動作します。Oracle公式サイトからJDK8をダウンロード、インストールした上で、anyenvのjenvを使って以下の環境を構築しました。

$ jenv add /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/
$ mkdir -p dev/gatling-test; cd $_
$ jenv local 1.8
$ java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

anyenvについては以下の記事をご覧ください。

anyenvを使って*env系をまとめて管理

以上の環境設定のあと、Gatling公式サイトからzipファイルをダウンロードして、中身を先程のディレクトリに展開してください。

Recorderで作成したシナリオを流す

まずはQuickstartをやってみます。GatlingにはRecorderというGUIツールが付属しており、これを使うことでブラウザ操作からテストシナリオを生成することができます。 ダウンロードしたGatlingのzipファイル中にある、bin/recorder.shを実行すると、以下のようなGUIが起動します。 これはGatlingの設定ツールです。ネットワーク環境によっては必要になるプロキシ設定を含む、HTTP(S)通信設定を行います。右下のStart!ボタンをクリックすると、キャプチャのGUIが新たに出現します。 この画面が出ている間、ブラウザ操作のキャプチャが始まります。キャプチャ中は、閲覧を除く、ページ遷移を伴う余計なブラウザ操作を控えましょう。
Quick startでは、この画面のTag機能を使いながら、デモアプリであるcomputer-database.gatling.ioを操作してシナリオを作成しています。一連の操作が終わったら、キャプチャGUI右上のStop&Saveをクリックします。そうすると、Gatlingディレクトリ内のuser-files/simulations/computerdatabase/にテストシナリオが生成されます。

user-files/simulations/computerdatabase
├── BasicSimulation.scala
└── advanced
    ├── AdvancedSimulationStep01.scala
    ├── AdvancedSimulationStep02.scala
    ├── AdvancedSimulationStep03.scala
    ├── AdvancedSimulationStep04.scala
    └── AdvancedSimulationStep05.scala

このシナリオを実行すると、以下のような出力を得られます。

$ bin/gatling.sh
GATLING_HOME is set to /Users/tannai.yuki/dev/gatling-test/gatling
Choose a simulation number:
     [0] computerdatabase.BasicSimulation
     [1] computerdatabase.advanced.AdvancedSimulationStep01
     [2] computerdatabase.advanced.AdvancedSimulationStep02
     [3] computerdatabase.advanced.AdvancedSimulationStep03
     [4] computerdatabase.advanced.AdvancedSimulationStep04
     [5] computerdatabase.advanced.AdvancedSimulationStep05
0 ### 0を入力してエンター
Select simulation id (default is 'basicsimulation'). Accepted characters are a-z, A-Z, 0-9, - and _
### 空のままエンター
Select run description (optional)
### 空のままエンター
Simulation computerdatabase.BasicSimulation started...

================================================================================
2018-07-31 12:15:45                                           5s elapsed
---- Requests ------------------------------------------------------------------
> Global                                                   (OK=2      KO=0     )
> request_1                                                (OK=1      KO=0     )
> request_1 Redirect 1                                     (OK=1      KO=0     )

---- Scenario Name -------------------------------------------------------------
[--------------------------------------------------------------------------]  0%
          waiting: 0      / active: 1      / done:0
================================================================================


================================================================================
2018-07-31 12:15:50                                          10s elapsed
---- Requests ------------------------------------------------------------------
> Global                                                   (OK=2      KO=0     )
> request_1                                                (OK=1      KO=0     )
> request_1 Redirect 1                                     (OK=1      KO=0     )

---- Scenario Name -------------------------------------------------------------
[--------------------------------------------------------------------------]  0%
          waiting: 0      / active: 1      / done:0
================================================================================


================================================================================
2018-07-31 12:15:55                                          15s elapsed
---- Requests ------------------------------------------------------------------
> Global                                                   (OK=4      KO=0     )
> request_1                                                (OK=1      KO=0     )
> request_1 Redirect 1                                     (OK=1      KO=0     )
> request_2                                                (OK=1      KO=0     )
> request_3                                                (OK=1      KO=0     )

---- Scenario Name -------------------------------------------------------------
[--------------------------------------------------------------------------]  0%
          waiting: 0      / active: 1      / done:0
================================================================================


================================================================================
2018-07-31 12:16:00                                          20s elapsed
---- Requests ------------------------------------------------------------------
> Global                                                   (OK=8      KO=0     )
> request_1                                                (OK=1      KO=0     )
> request_1 Redirect 1                                     (OK=1      KO=0     )
> request_2                                                (OK=1      KO=0     )
> request_3                                                (OK=1      KO=0     )
> request_4                                                (OK=1      KO=0     )
> request_4 Redirect 1                                     (OK=1      KO=0     )
> request_5                                                (OK=1      KO=0     )
> request_6                                                (OK=1      KO=0     )

---- Scenario Name -------------------------------------------------------------
[--------------------------------------------------------------------------]  0%
          waiting: 0      / active: 1      / done:0
================================================================================


================================================================================
2018-07-31 12:16:05                                          25s elapsed
---- Requests ------------------------------------------------------------------
> Global                                                   (OK=10     KO=0     )
> request_1                                                (OK=1      KO=0     )
> request_1 Redirect 1                                     (OK=1      KO=0     )
> request_2                                                (OK=1      KO=0     )
> request_3                                                (OK=1      KO=0     )
> request_4                                                (OK=1      KO=0     )
> request_4 Redirect 1                                     (OK=1      KO=0     )
> request_5                                                (OK=1      KO=0     )
> request_6                                                (OK=1      KO=0     )
> request_7                                                (OK=1      KO=0     )
> request_8                                                (OK=1      KO=0     )

---- Scenario Name -------------------------------------------------------------
[--------------------------------------------------------------------------]  0%
          waiting: 0      / active: 1      / done:0
================================================================================


================================================================================
2018-07-31 12:16:08                                          28s elapsed
---- Requests ------------------------------------------------------------------
> Global                                                   (OK=13     KO=0     )
> request_1                                                (OK=1      KO=0     )
> request_1 Redirect 1                                     (OK=1      KO=0     )
> request_2                                                (OK=1      KO=0     )
> request_3                                                (OK=1      KO=0     )
> request_4                                                (OK=1      KO=0     )
> request_4 Redirect 1                                     (OK=1      KO=0     )
> request_5                                                (OK=1      KO=0     )
> request_6                                                (OK=1      KO=0     )
> request_7                                                (OK=1      KO=0     )
> request_8                                                (OK=1      KO=0     )
> request_9                                                (OK=1      KO=0     )
> request_10                                               (OK=1      KO=0     )
> request_10 Redirect 1                                    (OK=1      KO=0     )

---- Scenario Name -------------------------------------------------------------
[##########################################################################]100%
          waiting: 0      / active: 0      / done:1
================================================================================

Simulation computerdatabase.BasicSimulation completed in 26 seconds
Parsing log file(s)...
Parsing log file(s) done
Generating reports...

================================================================================
---- Global Information --------------------------------------------------------
> request count                                         13 (OK=13     KO=0     )
> min response time                                    253 (OK=253    KO=-     )
> max response time                                    656 (OK=656    KO=-     )
> mean response time                                   359 (OK=359    KO=-     )
> std deviation                                        125 (OK=125    KO=-     )
> response time 50th percentile                        311 (OK=311    KO=-     )
> response time 75th percentile                        346 (OK=346    KO=-     )
> response time 95th percentile                        584 (OK=584    KO=-     )
> response time 99th percentile                        642 (OK=642    KO=-     )
> mean requests/sec                                  0.481 (OK=0.481  KO=-     )
---- Response Time Distribution ------------------------------------------------
> t < 800 ms                                            13 (100%)
> 800 ms < t < 1200 ms                                   0 (  0%)
> t > 1200 ms                                            0 (  0%)
> failed                                                 0 (  0%)
================================================================================

Reports generated in 0s.
Please open the following file: /Users/tannai.yuki/dev/gatling/gatling/results/basicsimulation-1533006940521/index.html

末尾に表示されるHTMLをブラウザで表示すると、以下のようなテスト結果を閲覧できます。

Scalaで記述したシナリオを流す

Scalaでシナリオを直接記述することもできます。Gatlingのテストシナリオを書くだけであれば、Scala言語を知らなくても問題ないとドキュメントに記載してあります。
Quick Startに沿って、以下のようなファイルをGatlingのuser-files/simulations/ScriptSample.scalaとして作成します。ファイル名とクラス名を一致させる必要があることに注意しましょう。Quick Start中のコードから、クラス名のみ変更しています。

package computerdatabase // 1

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

class ScriptSample extends Simulation { // 3

  val httpConf = http // 4
    .baseURL("http://computer-database.gatling.io") // 5
    .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") // 6
    .doNotTrackHeader("1")
    .acceptLanguageHeader("en-US,en;q=0.5")
    .acceptEncodingHeader("gzip, deflate")
    .userAgentHeader("Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0")

  val scn = scenario("BasicSimulation") // 7
    .exec(http("request_1") // 8
      .get("/")) // 9
    .pause(5) // 10

  setUp( // 11
    scn.inject(atOnceUsers(1)) // 12
  ).protocols(httpConf) // 13
}

bin/gatling.shを実行すると、選択可能なシナリオに先ほど作成したものが追加されています。

$ bin/gatling.sh
GATLING_HOME is set to /Users/tannai.yuki/dev/gatling/gatling
Choose a simulation number:
     [0] computerdatabase.BasicSimulation
     [1] computerdatabase.ScriptSample ### 追加したシナリオ
     [2] computerdatabase.advanced.AdvancedSimulationStep01
     [3] computerdatabase.advanced.AdvancedSimulationStep02
     [4] computerdatabase.advanced.AdvancedSimulationStep03
     [5] computerdatabase.advanced.AdvancedSimulationStep04
     [6] computerdatabase.advanced.AdvancedSimulationStep05

シナリオを選択して実行すると、結果がRecorderのときと同様のHTMLで出力されます。

まとめ

Gatlingというツールを使って、簡単な動作テストを行いました。HTML出力が見やすいこともあり、XMLでシナリオを記述するJMeterよりも使いやすいのではないかと思います。