RedmineをGatlingで負荷テストする


100名超で使うRedmineの負荷テストを実施する必要があって、なんとなくGatlingでやってみたので記録。
Redmineを普通に使う分にはパフォーマンス懸念がないんだけど、メール送信設定周りがボトルネックになることがあった。

事前準備

  • Gatlingをインストール
  • 簡単にテストするため、テスト対象のRedmineで以下を設定
    • Redmineの認証必須をオフにする
    • テストに使うプロジェクトを公開状態にして、ログインしなくてもチケット発行できるようにする

テストシナリオ作成

以下、GatlingのRecorderで操作を記録したものを少し書き換えたもの。
ポイントは、 CSRFトークンを保存して、POSTする時にHTTPヘッダーへ付ける こと。

操作としてやっているのは、以下の通り。

  • 新規チケット発行画面を表示
  • チケット発行
  • 上記を秒間3ユーザーが30秒間アクセスするようにする

なお、POST時に使っている RecordedSimulation_0001_request.txt は、Recorderで操作を記録した時にできるものなので、
それをそのまま使う。中身は、Formにどのような項目があって、各項目に何を指定するか。

import scala.concurrent.duration._

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

class RecordedSimulation extends Simulation {

  val url = "http://hoge.com/"
  val httpProtocol = http
    .baseURL(url)
    .inferHtmlResources()
    .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
    .acceptEncodingHeader("gzip, deflate")
    .acceptLanguageHeader("ja,en-US;q=0.7,en;q=0.3")
    .doNotTrackHeader("1")
    .userAgentHeader("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:54.0) Gecko/20100101 Firefox/54.0")

  val headers_0 = Map("Upgrade-Insecure-Requests" -> "1")

  val headers_1 = Map(
    "Content-Type" -> "multipart/form-data; boundary=---------------------------12071732112052",
    "Upgrade-Insecure-Requests" -> "1")

  val scn = scenario("RecordedSimulation")
    .exec(http("request_0")
      .get("/redmine/projects/hoge/issues/new")
      // CSRFトークン保存
      .check(regex("""<meta name="csrf-token" content="(.*?)" />""").saveAs("auth_token"))
      .headers(headers_0))
    .pause(2)
    .exec(http("request_1")
      .post("/redmine/projects/hoge/issues")
      .headers(headers_1)
      // HTTPヘッダーに保存したCSRFトークンを追加
      .header("X-CSRF-Token", "${auth_token}")
      .body(RawFileBody("RecordedSimulation_0001_request.txt")))

  setUp(scn.inject(constantUsersPerSec(3) during(30 seconds))).protocols(httpProtocol)
}

所感

  • 簡単に負荷テストをしたい時、Recorderの存在がありがたい
  • POSTをする時は、今回やったCSRFトークン保存のような小細工が必要になるので注意
  • Scalaが分からなくても、Javaができれば何となく書けるけど、分かった方ができることが増えそうな気がする
  • テスト後のレポートが結構充実していて、見ているとおもしろい