絶品ゆどうふのタレ

ふと気づいたことを綴るだけのメモ

負荷テストツールGatlingを触ってみた

負荷ツールとしてGatlingのことを少し前から耳にする機会が増えたので、利用してみることにした。

色々既出だとは思うが、公式のQuickstartに従って試してみたのでメモ。

GUIが必要だったので、今回は手元のMacで実行。

Gatlingとは

Java/Scala製の負荷テストツール

JMaterと似た感じのツールではあるが、

  • ハイパフォーマンス
  • 見やすいレポートHTML
  • developerフレンドリーなシナリオファイル

というのをウリとして謳っている。

たぶん、3項目とも対JMater(重い・レポート見づらい・XMLのシナリオつらい)を意識したメリットだろうなー。

なお、シナリオファイルは。。。

Gatling simulation scripts are written in Scala, but don’t panic!

わろた。

というわけで、触ってみる

Install

JavaとGalingをインストールする。Gatlingはunzipするだけ。

% brew cask install java
% wget https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/2.1.6/gatling-charts-highcharts-bundle-2.1.6-bundle.zip
% unzip gatling-charts-highcharts-bundle-2.1.6-bundle.zip

シナリオの作成

テストシナリオ

まず最初に、テストシナリオを決める。チュートリアルに従って以下のとおり。

Gatling Recorderによるシナリオの記録

シナリオの作成には、Gatling Recorderを使う。

Gatling Recorderは、proxyを通してブラウザアクセスして記録を取ことで、Scalaで書かれたシナリオファイルを自動生成してくれるツール

もちろん、自分でScalaを書いてシナリオ作りをしても良いが、今回は手軽にできるproxy式の手法をとる。

起動と設定

Gatling Recorderを起動する。

% cd gatling-charts-highcharts-bundle-2.1.6
% bin/recorder.sh

ツールが起動したら、初期設定として以下のように項目を埋める。

f:id:Yudoufu:20150613170429p:plain

この状態で、WebプロキシとしてGatling Recorderを設定する。

f:id:Yudoufu:20150613170522p:plain

ブラウザアクセスでシナリオを作る

Start を押すと設定に従ってproxyが起動するので、ブラウザでアクセスしながら記録を取る。

シナリオ作成時のTipsとして、変なpluginなどの影響がないようにsecret windowでやるとよさ気。 また、Gatling Recorderにはログの間にTAGを差し込む機能があり、シナリオの記録が綺麗になるのでそれも活用するといい。

ということで、以下の流れで操作を記録する。

f:id:Yudoufu:20150613170548p:plain

ここまで実行し終わったら、Stop & Saveを押すと、user-files/simulations/computerdatabase/BasicSimulation.scalaにシナリオファイルが保存される。

内容は以下のようになった。

package computerdatabase

import scala.concurrent.duration._

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._

class BasicSimulation extends Simulation {

    val httpProtocol = http
        .baseURL("http://computer-database.herokuapp.com")
        .inferHtmlResources(BlackList(""".*\.css""", """.*\.js""", """.*\.ico"""), WhiteList())
        .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
        .acceptEncodingHeader("gzip, deflate, sdch")
        .acceptLanguageHeader("ja,en-US;q=0.8,en;q=0.6")
        .userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.39 Safari/537.36")



    val uri1 = "http://computer-database.herokuapp.com"

    val scn = scenario("BasicSimulation")
        // Search
        .exec(http("request_0")
            .get("/"))
        .pause(5)
        .exec(http("request_1")
            .get("/computers?f=macbook"))
        .pause(2)
        .exec(http("request_2")
            .get("/computers/6"))
        .pause(10)
        // Browse
        .exec(http("request_3")
            .get("/"))
        .pause(2)
        .exec(http("request_4")
            .get("/computers?p=1")
            .resources(http("request_5")
            .get(uri1 + "/computers?p=2"),
            http("request_6")
            .get(uri1 + "/computers?p=3")))
        .pause(2)
        .exec(http("request_7")
            .get("/computers/72"))
        .pause(1)
        .exec(http("request_8")
            .get("/"))
        .pause(1)
        .exec(http("request_9")
            .get("/computers?p=1")
            .resources(http("request_10")
            .get(uri1 + "/computers?p=2")))
        .pause(3)
        .exec(http("request_11")
            .get("/computers/70"))
        .pause(10)
        // Edit
        .exec(http("request_12")
            .get("/"))
        .pause(1)
        .exec(http("request_13")
            .get("/computers/new"))

    setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
}

以上でシナリオの作成は完了。

テストの実行

今のシナリオを元に、Gatlingを起動する

% bin/gatling.sh

しばし待つと、実行候補となるシナリオの一覧が出てくるので、対象を選ぶ。(今回は0) なお、BasicSimulation以外の候補は、元々含まれているサンプル。

その他の質問もとりあえずEnterして実行する。

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
Select simulation id (default is 'basicsimulation'). Accepted characters are a-z, A-Z, 0-9, - and _

Select run description (optional)

Simulation computerdatabase.BasicSimulation started...

するとテストが実行され、最終的に結果が出力される

================================================================================
---- Global Information --------------------------------------------------------
> request count                                         18 (OK=18     KO=0     )
> min response time                                    191 (OK=191    KO=-     )
> max response time                                    414 (OK=414    KO=-     )
> mean response time                                   217 (OK=217    KO=-     )
> std deviation                                         64 (OK=64     KO=-     )
> response time 50th percentile                        195 (OK=195    KO=-     )
> response time 75th percentile                        197 (OK=197    KO=-     )
> mean requests/sec                                  0.441 (OK=0.441  KO=-     )
---- Response Time Distribution ------------------------------------------------
> t < 800 ms                                            18 (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: results/basicsimulation-1434181826508/index.html

結果の確認

results/basicsimulation-1434181826508/index.htmlにレポートが出力されたようなので、見てみる

% open results/basicsimulation-1434181826508/index.html

f:id:Yudoufu:20150613170606p:plain

思った以上にリッチなレポートが出力されていて、全体のrpsの状況や成功失敗のグラフ、各リクエストごとの詳細な情報、パーセンタイル値などが出た。

f:id:Yudoufu:20150613170622p:plain

f:id:Yudoufu:20150613170634p:plain

f:id:Yudoufu:20150613170721p:plain

今回のテストは動作チェック程度なので大したグラフになっていないが、これはまじめに負荷テストやるとすごく良さそう。 機会があったら、プロダクト側で使ってみたい。