Apache JMeterを使う
公式ホームページ から apache-jmeter-5.6.3.tar.gz をダウンロードして展開します。 ここでは C:\Wintools\apache-jmeter-5.6.3 に展開したとします。

同様にプラグインを導入します。 Pluginsのホームページにある、 JAR Fileのリンクから jmeter-plugins-manager-1.10.jar をダウンロードし、 C:\Wintools\apache-jmeter-5.6.3\lib\ext に配置します。


日本語化
JMeterの日本語化は簡単なので一応載せておきます。
C:\Wintools\apache-jmeter-5.6.3bin/jmeter.bat を編集、または jmeter-ja.bat など適当な名前でコピーして編集します。

rem set JMETER_LANGUAGE=-Duser.language="en" -Duser.region="EN"
set JMETER_LANGUAGE=-Duser.language="ja" -Duser.region="JP"

けれども以下の説明は引き続き英語のメニューにします(なんじゃそりゃ)


単一のURLの負荷テスト
ではまず、ローカルPC上のPHP内蔵サーバを起動して 「http://localhost:8080/shiten/index.php」という単一のURLに繰り返しアクセスするテストを実行してみます。
C:\Wintools\apache-jmeter-5.6.3\bin\jmeter.bat を実行すると、GUIが起動します。
左上のTest Planを右クリック⇒Add⇒Threads(Users)⇒Thread Group
追加された歯車アイコンのThread Groupを右クリック⇒Add⇒Sampler⇒HTTP Request

画面右の
Protocol[http] : http
Server Name or IP : localhost
Port Number : 8080

HTTP Request : GET
Path: shiten/index.php

HTTPリクエストパラメータは下の部分に「Add」で複数追加できますが、今は何も追加せずにおきます。

Thread Groupの画面に戻って、

Number of Threads : 10
Ramp-up Period : 10
Loop Count : 10
のように入力します。ここが負荷テストで掛ける負荷を指定する最も重要なパラメータ群です。

Number of Threads…送信するスレッド(=リクエスト「群」)の数。並んでテストする人数だと思うといいです。 同時アクセスへの耐久性を測るにはこの値を大きくしましょう。
Ramp-up Period…全スレッドがリクエストを作成するのに掛ける時間(秒)。 例えばNumber of Threadsが5でRamp-up Periodが10秒の場合、実行から2,4,6,8,10秒後に1つずつスレッドの起動が始まります。 間違えやすいのですが、この値はテストの総所要時間とは関係がありません。 この秒数が経過するとリクエスト送信が中断されるわけではなくて、 下のLoop Countの数のリクエストを送信し終わるまでは、テストは終わりません。
Loop Count…1スレッド(=リクエスト「群」)に含めるリクエストの数。各自が繰り返しテストする回数だと思うといいです。 1人が長時間利用し続けた場合の劣化の有無や、単純に総リクエスト数への耐久性を測るにはこの値を大きくしましょう。

再度
Thread Groupを右クリック⇒Add⇒Listener⇒View Results in Table
Thread Groupを右クリック⇒Add⇒Listener⇒Summery Report

Test Planに戻り、Nameを適当に: HelloMyPlan1 と名前を入力して、フロッピーのアイコン(Save)で保存します。
デフォルトのファイル名は HelloMyPlan1.jmx で、bin ディレクトリがデフォルトになります。

ではいよいよ、右向き緑→アイコン(Start)で実行します。

すると、PHP内蔵サーバのコンソールを表示している状態なら、そこにアクセス履歴が出るので、アクセスされたことが分かります。
実行が終わったら
View Results in Table
Summery Report
の画面を確認します(後述)

なお、Summery Reportの各列はマウスで引っ張って幅を変更できますが、再起動するとリセットされます (列の幅までjmxファイルに記録されるわけではありません)。
テストをやり直すときは「Clear All」ボタン(二重箒のアイコン)で過去の結果をクリアしてから実行すると良いです。

JMeterの画面の終了方法ですが、exitのようなメニューはないらしいので、ウィンドウの×ボタンで閉じます。 するとコンソールも一緒に終了します。


超簡単な結果レポートの見方
一番簡単なSummery Reportの例で見てみます。 まず気になるのはAvarage、Min、Maxという値ですが、 これは応答時間(Response Time)=全応答を受信完了するまでの所要時間で単位はミリ秒です。
重大な注意として、JMeterの用語では応答時間(Response Time)はLatencyとは違います。 Latencyとは一般に、最初の応答を受信するまでの所要時間のことです。 で、そのLatencyの方はSummery Reportには表示されません。 View Results in Table には個別の送受信に対して表示されるほか、その他のレポートの幾つかには集計に含まれます。


CUI実行
公式によると、より正確な結果を得るにはGUIではなくCUIの実行が推奨だそうです。
Windowsエクスプローラーで、HelloMyPlan1.jmxをつまんで jmeter-n.cmd にドロップすると、 コンソールが開いてアクセスが行われ、終わるとコンソールも閉じます。
HelloMyPlan1.log
HelloMyPlan1.jtl
というファイルが新規に作られます。中身は両方ともテキストファイルです。

またはjmeter.batを以下のように-nオプションを付けてコマンドラインで実行することも可能です。
jmeter -n -t [jmxファイル] -l [出力ログファイル] -e -o [Webレポートディレクトリ]
-h: このヘルプを出す
-n: CUI(Non GUI)Mode
-t: 処理対象の.jmxファイル
-l: 出力ログファイル名 (拡張子は.jtl)
-j: 実行ログファイル名
-e: generate report dashboard after load test
-o: output folder for report dashboard (存在しないかまたは空のディレクトリ)

テスト対象のWebサーバへのアクセスを確認した後、次のように実行できます。

cd C:\Wintools\apache-jmeter-5.6.3\bin
jmeter -n -t HelloMyPlan1.jmx -l C:\temp\report.jtl -e -o C:\temp\jmeter-output


プロキシーサーバによる画面遷移(シナリオ)自動記録
localhostではうまくいかないので、外部サイトで動作確認することにします。
Test Planを右クリック⇒Add⇒Theads⇒Thread Group
Thread Groupを右クリック⇒Add⇒Logic Controller⇒Recording Controller

Test Planを右クリック⇒Add⇒Non Test Elements⇒HTTP(S)Test Script Recorder
Portが8888になっていることを確認します。
次にTarget Controllerで 上で作ったRecording Controller をプルダウンから選択します。

Requests FilteringタブでURL Patterns Includeに、テストする画面遷移に共通で含まれる URLパターンを、正規表現で指定します。例えばホスト名で絞り込みたいなら一例で
.*nsnhnkmmkk.co.jp.*

とします。

準備ができたら、画面の中にある(ツールバーではない方の)緑の⇒矢印(Start)でいよいよプロキシーサーバを起動します。
Root CA Certificate created in bin directoryみたいなダイアログが数秒出て消えます。 その後に、Recorder: Transactions Controlというウィンドウが出ます。 これで記録準備はOKです。

次にアクセスするブラウザをプロキシーサーバ経由に設定します。 Chromeの場合、縦向き…アイコン⇒設定⇒プロキシ⇒パソコンのプロキシ設定を開くで localhost:8888 を有効にします。
または、コマンドライン(ショートカット)で 「C:\Program Files\Google\Chrome\Application\chrome.exe -proxy-server=localhost:8888」でも行けます。
この状態で、ブラウザで対象のURLにアクセスして、そこから辿れるメニューを適当に操作します。
Recoring Controllerの下にHTTP Requestがアクセスの度に1つずつ追加されているのを確認します。
終わったらブラウザ(PC)のプロキシ設定を元に戻します。

ここで一回保存しておきましょう。フロッピーのアイコン(Save)で HelloStarPhp1.jmx に保存しておきます。
保存したら、改めてそのシナリオに沿ってGUIで1回動作確認してみましょう。
Thread Groupを右クリック⇒Add⇒Listener⇒View Results in Table
Thread Groupを右クリック⇒Add⇒Listener⇒Summery Report
で、Test Planを選択してからツールバーの緑の右向き→Startで実行します。 1回だけなので一瞬で終わるはずです。 終わったら、上で追加したリスナーを見て、正常終了を確認します。

再実行したい場合は、二重箒のアイコン(Clear All)で結果をクリアしてから行うと良いでしょう。で、
Thread Groupを選んで、Number of Threadsなどを適当に入れれば、その間隔で複数回アクセスしてくれます。
例えば5,10,2としてStartすると、10秒の間2秒置きにスレッドが開始され、その間に5x2=10回アクセスされます。 1回のアクセスで5回の画面遷移があったとすると、50行が結果に作られているはずです。
※ちなみに、右上の経過時間はピッタリ10秒にはならず、8秒とかで止まります。これはそういうものらしいです。


jsessionidの対処
上の手順で記録したシナリオでそのままテストが行える場合もありますが、 ユーザー認証やURL直打ちアクセスチェックなどがあるアプリケーションの場合、 全く同じリクエストを投げてもエラーの応答になってしまい、実際のユーザーアクセスとは異なる通信になってしまうことがあります。 例えばServlet/JSPのWebアプリケーションの場合、 セッション管理のためにURLが「/app1/form.jsp?jsessionid=***」のような文字が含まれていると、適切な対処が必要になります。

といっても手順は割と簡単です。

  1. 記録された各HTTP RequestのURLや、内部のPath:の値に「?jsessionid=***」が含まれている場合、全て削ります。
  2. Thread Groupを右クリック⇒Add⇒Config Element⇒HTTP Cookie Manager
でOK。これでエラーにならずにセッション管理が行われると思います。


TOKENの対処
Struts Frameworkを使用したWebアプリケーションの場合、CSRF攻撃やボタンの二度押しなどの防止対策の目的で 「org.apache.struts.taglib.html.TOKEN」というリクエストパラメータを受け渡している物があります。 これも適切な設定に変更しないとエラーになり、実際のユーザーアクセスと異なる通信になってしまいます。 先のjsessionidの対処よりもかなり複雑ですが、一つずつやっていけば難しくありません。

  1. まず、パラメータに「org.apache.struts.taglib.html.TOKEN」という物が含まれている HTTP Request…ではなくて、 そのひとつ前、つまりそのURLに対してFormをSubmitとしているURLのHTTP Requestを右クリック⇒ Add⇒Post Process⇒Regular Expression Extractor
  2. 追加した画面で以下を入力します。

    Response Field to check : Body
    
    Reference Name : TOKEN
    Regular Expression : <input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="(.*)">
    Template : $1$
    Match No. : 空欄
    Default Value : 空欄
    

  3. そして今度こそ、パラメータに「org.apache.struts.taglib.html.TOKEN」という物が含まれている HTTP Requestを開き、そのTOKENのランダムな文字列が書かれている行を次のように変更します。

    Name : org.apache.struts.taglib.html.TOKEN
    Value : ${TOKEN}
    URL Encode? : チェックOFF(デフォルト)
    Includes Equals? : チェックON(デフォルト)
    

  4. 上記を、TOKENを渡している画面・受け取っている画面の対ごとに全て設定します。
    なお、Regular Expression Extractor は全て同じ名前でも構わないようですが、 私がテストした時は分かりやすいように名前を「RegularExpressionExtractorForTOKEN1」、2、3…と番号を振りました。

Misc. Topics Top

(first uploaded 2025/01/30 last updated 2025/07/11, URANO398)