Gatlingで負荷試験をする
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については以下の記事をご覧ください。
以上の環境設定のあと、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よりも使いやすいのではないかと思います。