負荷テストあれこれ-JMeterの使い方- | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

前回、「負荷テストあれこれ-Microsoft Web Application Stress Tool- 」で、簡易的に行える負荷ツールについて書きましたが、もう少し複雑なシナリオで負荷テストができるJMeterというツールについても書いてみたいと思います。


JMeterは、MS Web Application Stress Toolに比べ負荷ツールとしては多機能ですがその分、使い方はMS Web Application Stress Toolより複雑になっています。

負荷テストの対象や用途に応じて使いわけを行った方がスムーズに行えると思います。



JMeterがMS Web Application Stress Toolに比べて優れている点


・ Webアプリ以外のテストにも利用可能

FTPやSOAP、LDAP、JDBCリクエストのテストも可能。


参考: JmeterでDB負荷テストをやってみよう!


・ SSL通信下でもテスト可

JDK1.4以上の環境であればそのまま利用できますが、それ以外の場合は別途設定が必要です。

詳細は、JMeterのマニュアル 参照。


・ 複雑なテストシナリオに対応可能

テストの中でログインページは1度のみしか通過しないように設定したり、複数のページをランダムに遷移させたり、特定のページの遷移をループさせたり。


・ 複数の端末から負荷テストが可能で、テスト結果を一つに集約する事が可能


・ 負荷テストの結果をグラフにより可視化したり、CSV以外のフォーマットでレポートを出力することが可能。


・ メニュー等が日本語に対応している


と言ったところです。

一方で、JMeterの方が使いづらい点は、やはり多機能すぎて設定が複雑な点と、JMeter内で取り扱っている内部コードがUTF-8なため、リクエストパラメータや結果の受取りに支障がでる場合があります。

この辺はそういう仕様なのでしょうがないかもしれませんが・・・。

対応方法としては、下記が参考になるかもしれません。


日本語パラメータの POST/GET @ Hiki


複雑なテストシナリオを作る事が出来ると言っても、そもそも静的なページしかないサイトに対して負荷テストをするのであれば、そのような複雑なシナリオは必要ないでしょうからMS Web ApplicationStress ToolやApache Benchなどを利用した方が良いでしょう。



JMeterの使い方


JMeterを利用したWebアプリの負荷テストの手順としては


1. スレッドグループの追加


スレッドグループは、一連の負荷テストのシナリオ(リクエスト)をまとめたものです。

「テスト計画」を右クリックし、「追加」→「スレッドグループ」で追加できます。



2. HTTPリクエストサンプラーの追加


1.で追加したスレッドグループを右クリックして「追加」→「サンプラー」→「HTTP リクエスト」で追加します。

HTTPリクエストサンプラーは、Webサーバーに対して一つのリクエストを送信します。



3. HTTPリクエストサンプラーの各項目を設定


[ 名前 ]

リクエストの名称。テスト結果を分かりやすくする為に何のページかを記載しておいた方が良いでしょう。


[ サーバ名又はIP ]

テストするWebサーバーのFQDNもしくはIP


[ ポート番号 ]

テストするWebサーバーが受付けるHTTP又はHTTPS用のポート番号(省略可能)


[ プロトコル ]

httpもしくはhttps


[ メソッド ]

後述する「リクエストで送るパラメータ」を設定した場合、それらのパラメータをどのメソッドで送るか。

パスワードとか重要な情報を送るのであれば、GETにしてしまうとWebサーバーにそのパスワードのログが残ってしまう為、POSTにしておいた方が無難。

あとは、実際のアプリの挙動どおりのメソッドを設定してあげればよいと思います。


[ パス ]

リクエストを送るパス。ドキュメントルート以下から記載する。

http://hogehoge.com/test/index.html 」へリクエストを送信する場合は「/test/index.html」


[リクエストで送るパラメータ]

そのリクエストに一緒に送信するパラメータ。

実際の変数名とその値を入力します。エンコードする場合は、「Encode」のチェックを入れておきます。


※ JMeterは、リクエストで送るパラメータは全てUTF-8で送る為、注意が必要です。


[ オプションタスク ]

この中にある、「全てのイメージとアプレットを繰り返しダウンロードする(HTMLファイルのみ)」にチェックを入れておかないと、フレームなどに対してリクエストした際にそのフレーム内から呼び出されるファイルを呼び出してくれません。

フレームがきられたサイトのテストをする際は、上記にチェックを入れておきましょう。



4. シナリオに沿うように3.の作業を繰り返し


ログインページ→Aページ→Bページというシナリオの場合、3つのHTTPリクエストサンプラーを作っておきます。

それぞれのページ遷移の際に、パラメータが必要な場合はそれぞれの前のページでそのパラメータを送信するようにサンプラーにセットしておく必要があります。

例えば、Bページでログイン処理をするのであればAページでIDとパスワードなどのパラメータを送信してやる必要があります。



5. ロジックコントローラをセット


最初にJMeterは複雑なテストシナリオを設定する事が可能と書きましたが、そのために設定するのがこのロジックコントローラです。

ロジックコントローラの設定は、スレッドグループを右クリックし「追加」→「ロジックコントローラ」から追加するコントローラを選択します。

このコントローラにぶら下がるHTTPリクエストサンプラーがその挙動に従うようになります。


[ 一度だけ実行されるコントローラ ]

その名のとおり、テストシナリオの中で一度だけしか実行されないようにする為のコントローラです。

ログイン処理など、一連のシナリオの中で一度しかテストシナリオとして必要ない場合に設定します。


[ ループコントローラ ]

一連のリクエスト処理をループさせます。

スレッド全体として、ループ回数を設定できますが特定のリクエストグループのみを重点的にループさせたい場合などに使用できます。


[ インタリーブコントローラ ]

ぶら下げているHTTPリクエストサンプラーの1つを実行します。

負荷テストが繰り返し実行された場合、インタリーブコントローラにぶら下げたHTTPリクエストサンプラーはその登録順で1つずつ実行されていきます。

例えば、A・B・Cの3つのHTTPリクエストサンプラーがぶら下がっていた場合、1回目のテストではAだけが、次はBだけが、3回目はCだけが実行されていきます。

4回目以降は再びAから実行されます。


[ 乱数コントローラ ]

ぶら下げているHTTPリクエストサンプラーのうちランダムに選んだ1つを実行します。

インタリーブコントローラは登録順で実行されますが、乱数コントローラは任意のものが1つだけ実行されます。


[ ランダム順序コントローラ ]

ぶら下げているHTTPリクエストサンプラーを任意の順番で実行します。

インタリーブコントローラや乱数コントローラとは違い、ぶら下げている全てのHTTPリクエストサンプラーが実行されます。


[ シンプルコントローラ ]

機能としては何もありません。

特定のHTTPリクエストサンプラーを束ねる為に使用します。

これは、テスト計画を見やすくする為です。



少し複雑なテストシナリオの例)


例えば、自分が管理しているサイトの中でユーザーがよく利用されるメニューと言うのを把握していたとします。

また、ユーザーがサイトにログインしてからログアウトするまで利用するメニューが、平均は3つで各メニューはお決まりの遷移パターン(メニューAを利用するにはその中の小メニュー1→小メニュー2と遷移する)があるとしま。

この場合、ログインし幾つかのよく利用されるメニュー(ここでは7つ(メニューA~メニューG)としてます)

の中からから3つをランダムに選びページを遷移するという一連のテストシナリオを作ります。


例えば


トップページ

 ↓

ログイン画面

 ↓

メニューC(小メニューC-1 → 小メニューC-2)

 ↓

メニューF(小メニュー F-1 → 小メニューF-2 → 小メニューF-3)

 ↓

メニューA(小メニューA-1 → 小メニューA-2)


と言うような流れとなります。メニューC、F、Aは7つあるメニューの中からピックアップした任意の3つとなります。

このシナリオで何回か繰り返しを行います。


このテストシナリオとしてJMeter上で登録した場合は、下記のようになります。


J-Meter-シナリオ


最初のループコントローラは3回ループするように設定され、その中の乱数コントローラでメニューA~メニューG(ループコントローラ)が実行されます。

メニューA~メニューGはその内部でお決まりの遷移パターン(小メニュー1~N)を移動するようにするため、メニューA~メニューGは実際はループコントローラで指定し、1回のみループするようにセットしています。

(でなければ乱数コントローラは各小メニューの中から任意のものをピックアップして実行しますので、小メニューA-1→小メニューG-1→小メニューF-3などの想定外の動きをしてしまいます。)

この結果を、「結果をツリーで表示」のリスナー(後述)で受け取ってみると


JMeterTestTree


少々偏りがありますが、上図のようにランダムのメニューでテストを行う事ができました。

各メニューは想定どおり、その小メニューを順番で移動しています。


また、よりリアルなテストシナリオにする為にタイマを使って各HTTPリクエストサンプラー間のアクセスのタイミングをずらす事もできます。

これは、ユーザーが実際にサイトにアクセスしてそのコンテンツを読んだりする時間をテストシナリオに組み込む為のものです。

タイマは、一定期間の同じ時間(ミリ秒)待たせる「定数タイマ」や、指定の範囲でランダムの時間(ミリ秒)待つように設定できる「一様乱数タイマ」や「ガウス乱数タイマ」などがあります。



6. 設定エレメントの登録


設定エレメントは、HTTPリクエストの中でパラメータ以外にセットしておく必要がある環境をセットできます。

設定エレメントは、スレッドグループにぶら下げた場合はそのテスト全体に影響しますが、特定のHTTPリクエストサンプラーにぶら下げた場合は、そのサンプラー内でしか有効に働きませんので注意してください。

よく利用する設定エレメントとしては


[ HTTP認証マネージャ ]

Basic認証用のIDとパスワードをセットできます。

リクエスト送信先がBasic認証で保護されていた場合に利用します。

(テストする際にBasic認証を解除するだけでも良いと思いますが・・・)


[ HTTP クッキーマネージャ ]

認証などのCookieが利用されている場合に利用します。

アクセスしたサイトで埋め込まれるCookieを保持する役目と、サイトアクセスの際に予めセットしておく必要があるCookieを登録しておく2つの機能があります。

後者の場合は、そのCookie名と値をセットしておきます。


JMeter-CookieMenu


上図は、HTTPクッキーマネージャを設定した例ですが、クッキーマネージャを何処にセットするかで影響が異なってきます。(他の設定エレメントも同様)


スレッドグループの直下にぶら下げた場合(全体で必要なCookie)、それは全てのHTTPリクエストサンプラーに影響します。

メニュー1のリクエストサンプラーにぶら下げている「メニュー1で必要なCookie」は、メニュー1のHTTPリクエストサンプラー内でしか有効になりません。

セッション情報をCookieにセットしているなら全体に影響するように、スレッドグループの直下にクッキーマネージャを配置しておく必要があります。



7. リスナーを追加


リスナーは、Webサーバーに投げたリクエストの結果を受取り、そのレポートを作ってくれる機能です。

レポートの形式により、リスナーの種類が異なります。

よく使うリスナーとしては


[ 統計レポート ]

各HTTPリクエストごとのレポートを出力します。見方は後述。


JMeter-統計レポート


[ 結果をツリーで表示 ]

シナリオが正常に行われたかが確認できます。

「統計レポート」では、エラーがあればエラー率が表示されますが具体的にどの箇所でエラーになったのかが分かりませんので、この結果ツリーから確認を行えばよいです。

リクエストして受け取ったコードや、そのHTMLタグをJMeter上に表示させる事もできます。

ただし、受け取る文字コードがUTF-8のためその他のコードで書かれたサイトは文字化けしますが・・・。



[ グラフ表示 ]

「統計レポート」の結果をグラフ化してくれます。



8. 負荷レベルを設定


設定したテストシナリオでどれ位のレベルの負荷をかけるのかは、スレッドグループの項目にて設定できます。

ここにある、「スレッド数」、「Ramp-Up期間」、「ループ回数」でそのレベルを調整します。


[ スレッド数 ]

スレッドグループでまとめた一連のリクエストをいくつ実行するかを設定します。

スレッド数は、Ramp-Up期間で設定した秒数の間に幾つスレッド数を生成するのかを設定する値になります。

詳しくは、下記記事を参照してください。


負荷テストあれこれ-JMeter 負荷のかけ方、レポートの見方-



[ ループ回数 ]

一連のテスト(スレッド数)を何回実行するかです。


総テスト回数(総スレッド数) = スレッド数 × ループ回数


という関係になります。



[ Ramp-Up期間 ]

Ramp-Up期間とは、上記の総テスト回数(総スレッド数)を何秒間で生成するのかを設定するかをセットします。


もしこの値を「0」にした場合は、即時に全てのスレッドが生成されます。



1秒あたりに生成されるスレッド数は、スレッド数とループ回数の関係によって異なってきます。

詳しくは、下記の記事を参照してください。


負荷テストあれこれ-JMeter 負荷のかけ方、レポートの見方-


※ 当然これらは、テストを行う側のPCの性能にも影響が出ますので、注意が必要です。


Ramp-Up期間は、あくまでスレッドの生成が全て完了するまでの期間を表したものです。

スレッド内にタイマをセットしていた場合、リクエスト間でタイマの秒数待ちが発生するために実際にテストが完了する時間とRamp-Up期間はイコールにはなりません。



9. テストを実行


JMeter上部メニューの「実行」→「開始」で開始されます。

テストが実行中であるかどうかを確認する方法は


・ 再度、「実行」メニューを見てみて「開始」が網掛けになって実行されていない


・ 登録しているリスナーの結果を見てみる(動きがなくなったら終了)


・ 右上に緑色のランプが実行していれば実行中

 もう少し大きく表示してほしい・・・


JMeter-Test


より詳しいJMeterの使い方は下記が参考になるかと。



JMeter @TECHSCORE


JMeterによるWebサーバ性能評価の勘所 @IT


後はもちろんJMeterのマニュアル も。



2.のHTTPリクエストサンプラーの追加は、想定するシナリオの分だけ追加しなければなりませんがかなり手間になる為、HTTPプロキシサーバの機能を利用すればある程度簡略化できます。


また、ここでは記載しませんでしたがよりリアルなテストシナリオにする為に、タイマを利用し一連のスレッド内のリクエストに遅延を生じさせることも可能です。

利用方法は少し癖があり、市販の負荷テストツールに比べれば見劣りする部分はありますが複雑なテストシナリオを組んだり、レポートの種類も豊富なのでまずは検討材料に入れてみて

利用してみるのも良いかもしれません。