負荷テストツールGatlingを触ってみた
負荷ツールとしてGatlingのことを少し前から耳にする機会が増えたので、利用してみることにした。
色々既出だとは思うが、公式のQuickstartに従って試してみたのでメモ。
Gatlingとは
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
シナリオの作成
テストシナリオ
まず最初に、テストシナリオを決める。チュートリアルに従って以下のとおり。
測定対象とするのは http://computer-database.herokuapp.com/ というページ
- これは、いろんなPC等コンピュータのモデル情報を登録するCGM的なサイト
- Play framework製!
- 自分のローカルで動かしてもいい https://github.com/playframework/playframework/tree/2.2.x/samples/scala/computer-database
リアルなユーザーのシナリオとして、以下の様な想定でテストする
- ユーザーがアプリケーションにアクセス
-
mackbook
で検索 - 関連するモデルを開く
- homeページに戻る
- これを繰り返す
- ユーザーが新しいモデルを登録する
Gatling Recorderによるシナリオの記録
シナリオの作成には、Gatling Recorderを使う。
Gatling Recorderは、proxyを通してブラウザアクセスして記録を取ことで、Scalaで書かれたシナリオファイルを自動生成してくれるツール。
もちろん、自分でScalaを書いてシナリオ作りをしても良いが、今回は手軽にできるproxy式の手法をとる。
起動と設定
Gatling Recorderを起動する。
% cd gatling-charts-highcharts-bundle-2.1.6 % bin/recorder.sh
ツールが起動したら、初期設定として以下のように項目を埋める。
この状態で、WebプロキシとしてGatling Recorderを設定する。
ブラウザアクセスでシナリオを作る
Start
を押すと設定に従ってproxyが起動するので、ブラウザでアクセスしながら記録を取る。
シナリオ作成時のTipsとして、変なpluginなどの影響がないようにsecret windowでやるとよさ気。 また、Gatling Recorderにはログの間にTAGを差し込む機能があり、シナリオの記録が綺麗になるのでそれも活用するといい。
ということで、以下の流れで操作を記録する。
- Recorder側で
Search
タグを追加 - ブラウザでhttp://computer-database.herokuapp.com/ のトップに移動
mackbook
で検索Macbook Pro
をBrowse
タグを追加- http://computer-database.herokuapp.com/ のトップに戻る
- 何回か
Next
ボタンで遷移 - いくつかページを開いてみる
Edit
タグを追加- http://computer-database.herokuapp.com/ のトップに戻る
Add new computer
を押す- (チュートリアルではもっとあるけど、ここまでにした)
ここまで実行し終わったら、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
思った以上にリッチなレポートが出力されていて、全体のrpsの状況や成功失敗のグラフ、各リクエストごとの詳細な情報、パーセンタイル値などが出た。
今回のテストは動作チェック程度なので大したグラフになっていないが、これはまじめに負荷テストやるとすごく良さそう。 機会があったら、プロダクト側で使ってみたい。