Gatlingで負荷試験を楽にするTips

こんにちは。
@Kuchitamaこと国平です。

Scalaアドベントカレンダー in Adventarの8日目の記事を担当いたします。
昨日の記事は@dakatsukaさんのFinch + MySQLでREST APIサーバを構築するでした。

さて、私が8月に入社してから進めていたプロジェクトの情報がついに公開できるようになりました。
share-wis.comのリプレースがそのプロジェクトです。

これまでのShareWisは、ユーザ投稿型の知識共有サービスでしたが、

この度、知識との出合いというコンセプトに立ち戻って、
ちょっとしたスキマ時間に様々な知識に触れることができるような、
動画主体の スナックラーニングサービス として近日中に生まれ変わります。

今回のプロジェクトでは、より多くの方のスキマ時間を有意義なものにするため、
パフォーマンスが重要課題として上がりました。

Webサービスの開発において、安定してパフォーマンスを保てるサービスを公開するために、負荷試験は欠かすことが出来ません。
今回のShareWisリプレースでは、その負荷試験にGatlingという負荷試験ツールを利用したので、その際の知見を共有します。

今回の記事のポイント

  • Gatlingで負荷試験を行った
  • 負荷試験のシナリオをsbtプロジェクトとして管理した
  • 実行環境の構築が楽になる
  • IntelliJ IDEA などのIDE利用が捗る

Gatlingとは

GatlingはScala製の負荷試験ツールです。
同様のツールとしては、JMeterが有名かと思います。

JMeterも優れたツールなのですが、xmlでテストシナリオを管理するのが面倒に感じられる方も多いのでは無いかと思います。
対して、Gatlingでは、Scalaのコードでシナリオを記述でき、しかも、Scalaの表現力を活かした内部DSLが用意されています。

そのため、プログラマにとっては試験のシナリオがかなり扱いやすくなると思います。

Gatling自体の使い方については、既に多くの情報があると思いますので、今回の記事ではGatlingのテストコードを、プロダクトと同じsbtプロジェクトに含めて、sbtから実行する方法をまとめます。

Gatlingをsbtプロジェクトに含める

ShareWisは、PlayFramework2.4 で開発しています。
そのため、元々 sbtプロジェクトで、Scalaコードを扱っています。

そのため、Gatlingのテストコードも同じリポジトリで、同じsbtプロジェクトに入れてしまうのが、管理が楽になりますし、テストコードを書く際にも、IntelliJ IDEA などのIDEの恩恵を楽に受けれるようになります。

sbtの設定

今回、Gatlingの実行は、プロダクトコードの実行やテストとは分けて動かしたいので、負荷試験用にsbtのサブプロジェクトを作成しました。

plugins.sbt

addSbtPlugin("io.gatling" % "gatling-sbt" % "2.1.0")

build.sbt

val commonSettings = Seq(
version := "1.0-SNAPSHOT",
scalaVersion := "2.11.6"
)

val appDeps = Seq(
// ...
)

// Gatlingの依存ライブラリ
val stressTestDeps = Seq (
"io.gatling.highcharts" % "gatling-charts-highcharts" % "2.1.7" % Test,
"io.gatling" % "gatling-test-framework" % "2.1.7" % Test
)

// プロダクトのプロジェクト
lazy val root = (project in file(".")).enablePlugins(PlayScala)
.settings(
// settings...
))

// 負荷試験用のプロジェクト
lazy val stressTest = (project in file("stress-test")).enablePlugins(GatlingPlugin)
.settings( commonSettings ++ Seq(
name := "stress-test",
libraryDependencies ++= stressTestDeps
))

テストシナリオの追加

stress-test/src/test/scala以下に io.gatling.core.Predef.Simulattion を継承したクラスを用意しテストシナリオを記述します。

このとき、IDEにsbtプロジェクトとして読み込ませていれば、下図のように補完が効くはずです。

screenshot_1207_001

負荷試験の実行

この様に、プロジェクトを用意することで、負荷試験の実行時には、下記のようにsbtで stressTest/test タスクを実行するだけで、負荷試験を行うことが出来ます。
(PlayFrameworkのプロジェクトで試す場合は、sbtをactivatorに適宜読み替えてください)

$ sbt stressTest/test

負荷試験の実行が完了すると、stress-test/target/gatling以下に結果を保存したディレクトリが作成されます。
ディレクトリ内の、index.htmlをブラウザで開くと、Gatlingによって生成されたテスト結果を確認することが出来ます。

screenshot_1207_002

サンプルプロジェクト

今回、実際にGatlingを試せるように、サンプルプロジェクトを用意しました。

ShareWis/play-bookshelf

このプロジェクトは PlayFramework2.4 のActivatorで構築されていますので、Java7以降の実行環境があればcloneする、もしくはGitHubからアーカイブをDLしてすぐに実行できます。

まず、クローンして、playを起動します。

$ git clone https://github.com/ShareWis/play-bookshelf.git
$ cd play-bookshelf
$ git checkout -b refs/tags/gatling-sample
$ ./activator run

もうひとつ、端末のウィンドウを開いて、Gatlingを実行します。

$ cd play-bookshelf
$ ./activator stressTest/test

1分程度でテストが完了して、stress-test/target/gatling以下に結果が保存されます。

まとめ

Gatlingのテストコードをsbtプロジェクトにまとめることで、下記のメリットが得られました。

  • プロダクトコードと負荷試験のテストコードを一元管理できる
  • テストコードの編集時にIDEの恩恵を楽に受けられる
  • sbtのタスクとして負荷試験を実行できる

近日リプレースされる新しいShareWisでは、このようにして皆様に可能な限り快適にご利用いただけるよう準備を行っています。

一人でも多くの方に、素敵な知識との出合いを提供できるよう公開準備を進めていますので、ご期待下さい!

参考

  • http://gatling.io/#/
  • http://qiita.com/FScoward/items/7e865103c0fa61746562

最後に

明日の ScalaAdventCalener in Adventar は、 Shinpeimさんの記事です。

まだまだ、カレンダーに空きがあるので、皆様いろいろなScalaネタを投稿してみると良いんじゃないでしょうか。