JMeterでの負荷・性能テスト

システム開発のでは製造・構築フェーズが終わると当然のことながら各種テストを行う。今回は、その中でもよくシステムテストと呼ばれるフェーズに含まれることの多い負荷・性能テストに関するお話。

<テストツールの検討と選定>

私の経験では、これまで行ってきたテストでは、規模やシステムの特性に応じて以下のようなテストツールを選定・使用してきた。

色んなツールや方法があるが、ツール選定の基準、決め手には以下のようなものがある。

  • テストに掛けられるコスト
  • テストするプロトコル(HTTP/HTTPS/SOAP/JDBCなど)
  • 取得したい性能メトリック(アプリのレスポンス、NW帯域使用量など)
  • テスト実施時間(連続稼動テスト/バースト性テストなど)

さて、そんな中で今回は経験上それほど弱点の少ない(と思っている)JMeterを使ったテスト方法について、Tipsをいくつか紹介する。なお、JMeterについての詳細な説明は割愛するが、簡単に言えば「Jakartaプロジェクトで開発が進められていパフォーマンス計測用のJavaアプリ」である。現在では、Webアプリケーション以外のさまざまなものに対してもテストできるように拡張されている。

JMeterを使ったテストの勘所〜リスナーの選択〜>

比較的長い時間のテストを行う場合、テスト用端末にとってはJMeterで負荷を発生させること自体がかなりの負荷となる場合がある。いわゆるJMeterがヘタレた状態だが、こうなるのには次のような原因がある。それは、本来かけたい負荷以外にもJMeterが仕事をしており、これがテスト端末の「必要以上の」高負荷状態を生み出している、ということだ。

JMeterによるログではCSVデータを出力することができる。JMeterでテストをしたことがある方で思ったほどの負荷が出せていないという方がいるかと思うが、例えばそんな時、CSVの出力以外にも統計レポートやサマリレポートなどのリスナーを表示・使用してしないだろうか?

無論実施するテストにもよるが、テスト結果を解析をしたりテストの結果報告書をまとめる段階では、個人的にはCSVのRawデータを取得しておけばそれで事足りると考えている。つまり、リアルタイムで統計レポートやサマリレポートなどのリスナーを動かすことは、テスト中の安心感はあるとしても、シビアな負荷テストには適しておらず、テスト端末のリソースを有効活用できていない可能性があるということだ。

こんなことを考えながら試行錯誤した結果、JMeterを使った性能テストにおいて取得すべきJMeterのRawデータを確保するには、Simpe Data Writerというリスナーを1つだけ使用すれば十分であるという結論に至った。Simple Data Writerは、リアルタイムな画面表示などは行わず、ひたすらCSV形式でデータをファイルに書き出すのみ。

JMeterの設定ファイルをカスタマイズする>

JMeterは当然デフォルトの設定で起動しても十分テストを行うことはできるが、JMeterの設定ファイル「jmeter.properties」の設定を適切にカスタマイズすることで、よりJMeterを活用することができる。ここでは、JMeterのbinディレクトリ配下に存在するjmeter.propertiesファイルのカスタマイズ内容について延べる。

注意:Linux/UNIX系OSの場合、設定ファイルの権限がread only権限なので更新権限を付与すること。

JMeterパラメータ 説明
language=en_US ログファイルが日本語(UTF-8)にならないため、Excelで結果データを整形する際に読みやすい。日本語の場合にはUTF-8の文字化けが原因でフィールドとデータがずれる。
jmeter.save.saveservice.output_format=csv デフォルトでCSV出力する。
jmeter.save.saveservice.label=false ログファイルにラベルは要らないので削除(出力例:「HTTP Request」)
jmeter.save.saveservice.timestamp_format=HH:mm:ss Excelで開いたときにタイムスタンプが判りやすくする。※Perlを使用して解析する前提であれば、localtime関数で処理すればよい話なのでデフォルトの方がよいかもしれない
jmeter.save.saveservice.print_field_names=true CSVのフィールド名を保存
jmeter.save.saveservice.data_type=false データタイプは自明なので不要
jmeter.save.saveservice.response_message=false レスポンスコードがあれば自明なので不要
jmeter.save.saveservice.subresults=false XML出力用の設定の為、不要
jmeter.save.saveservice.assertions=false XML出力用の設定の為、不要
jmeter.save.saveservice.thread_counts=true そのデータが記録された際のスレッドの数。この数値が小さいデータは統計時に除外するべき。

なお、上記bin/jmeter.propertiesファイルとは別に、Jmeterの起動スクリプト内の「set HEAP=-Xms256m -Xmx256m」も、当然ながらJMeterを実行するマシンの環境に合わせて適切なヒープサイズを設定する必要があるので、注意すること。※起動スクリプトWindowsではbin/jmeter.bat、Linuxではbin/jmeterファイル。

CSVサンプル>


カラムヘッダ 説明
timeStamp 開始時刻
elapsed リクエストを送出してからレスポンスが終了するまでの経過時間(ms)
responseCode HTTPレスポンスコード
threadName JMeterスレッド名。複数のスレッドグループを使用しないのであればあまり使いどころが無い為、configureで個別に消しても良い。
success リクエストに対して結果が返ってきたかどうか
bytes 送受信バイト数
grpThreads そのスレッドグループ内でアクティブなスレッド数
allThreads 全てのスレッドグループのトータルアクティブスレッド数
Latency リクエストを送出してから最初の1バイトが帰ってくるまでの経過時間(ms)

よりデータを減らしたい場合・増やしたい場合は、リスナーのconfigureから適宜取捨選択する。

<テストを行う為の最小限の設定>

  1. Thread Groupを作成
    • 実行多重度(ユーザ数)や実行回数を設定。
      • users:同時実行数
      • rampup Period : 上記「users」を増やしていくタイミング。単位は秒。
      • Loop Count : 何回実行するか
  2. HTTP Requestを作成
    • どのURLにアクセスするのかを設定
      • Server Name or IP : サーバ名を指定(URLではないので注意)
      • Path : URLのパス部分(トップなら/)を指定
  3. Simple Data Writerを作成
    • 上記CSVファイルをどこに保存するかを設定。
  4. Constant Throughput Timerを作成
    • 分間どれくらいのリクエストを送信するかを設定する。
    • なんらかのTimerを設定しないと、JMeterは連続的にリクエストを投げ続ける為、JMeter実行PC/テスト先サーバー共に大きな負荷が発生する。
      • Target throughput (in sample per minute) : 1分間に各Samplerが何回実行されるかを定義する。秒間10リクエストを期待するのであれば600 ( = 10 x 60) と設定する。
      • Calculate Throughput based on : 「all active threads in current thread group」を設定する。スレッドグループ内の全てのスレッド(実行単位)の実行回数の合計が上記「Target throughput」になるようにする。