第6回:入力パラメータを外部ファイルから読み込むの対応で、負荷テストで動作するシナリオが完了しました。最後に負荷テストの負荷に関わる修正を行っていきます。
主要な修正箇所は次の通りです。
- タイマ
- スレッド数とRamp-Up期間、ループ回数
- スレッド数などの変数化
- サンプラーエラー後のアクション
- リスナーの無効化
また、テスト実行イメージは次の通りです。
動画解説もあるので、そちらも併せて参考にしてください。
タイマ
デフォルトの状態でシナリオを実行すると、前のリクエストが終了した直後に次のリクエストが行われるようになっています。今回のシナリオで言えば、トップページへのアクセスが完了した直後に、ログインページへ遷移するような形です。そのため、複数スレッドで同時アクセスを行うと、極度のアクセス集中状態となり、正常な負荷試験ができません。
タイマの設定を入れることで、リクエスト間の待ち時間の設定が可能になります。実際のユーザの動きに近い設定を入れることで、より現実的なテストを行うことが可能です。
よく利用するタイマは次の通りです。
タイマ | 概要 |
---|---|
常数タイマ | 一定間隔で待ち時間を設定 |
一様乱数タイマ | 乱数を使い待ち時間を設定 |
ガウス乱数タイマ | ガウス分布を使って待ち時間を設定 |
一様乱数タイマの追加と設定
今回は一様乱数タイマを使って、各リクエストの間に3~5秒の待ち時間を入れる設定をいれていきます。
- スレッドグループ->タイマ->一様乱数タイマ
※リクエストごとに個別の設定を入れたい場合は、「HTTPリクエスト」の直下に入れる必要があります
3~5秒の待ち時間を入れるので、次のように設定を行います。
設定項目 | 値 |
---|---|
最大遅延時間(ミリ秒) | 2000 |
遅延時間オフセット定数(ミリ秒) | 3000 |
一様乱数タイマの確認
「結果を表で表示」リスナーを作成し、動作確認を行ってみます。
- スレッドグループ->追加 -> リスナー->結果を表で表示
リスナー追加後に実施をしてみて、「StartTime」に待ち時間が入っていれば正常です。
スレッド数とRamp-Up期間、ループ回数
スレッド数とRamp-Up期間、ループ回数の指定を行います。
スレッド数
スレッド数は、同時接続を行う人数設定です。1の場合は1人がアクセスを、10の場合は10人の人が同時アクセスするシュミレーションが可能です。
Ramp-Up期間
Ramp-Up期間はスレッドがすべて起動するまでにかかる時間の設定です。この設定がされていない場合は、全スレッドが同タイミングで起動することになり、想定以上の高負荷状態になる可能性があります。適切な期間を設定することで順次アクセスを増やしていき、実体に近い状況を作り出すことが必要です。
ループ回数
ループ回数は、各スレッドがシナリオ実行を繰り返す回数です。複数回指定することで、より精度の高いテストが可能になります。
設定
ここでは、10人(スレッド数)が30秒の間に同時アクセス(Ramp-Up期間)し、同じ操作を10回繰り返す(ループ回数)想定で設定をしてみます。
スレッドグループのスレッドプロパティの設定を入れていきます。
スレッド数などの変数化
限界スループットの確認方法へ記載した通り、限界スループットを確認するためには、スレッド数の値を変化させてスループットの推移を確認していく必要があります。都度シナリオを修正してスレッド数を変更するのは非効率なので、スレッド数の値を外部から設定可能なようにしていきます。
変数化は次のように設定していきます。
変数宣言 | コマンド実行時の指定方法 |
---|---|
${__P(変数名,初期値)} | -J変数名=1 |
${__P(変数名)} | -J変数名=1 |
「thread」というパラメータで外部指定し、指定がない場合は「1」にする場合は次のように記載します。
- ${__P(thread,1)}
同じように、ランプアップ期間とループ回数についても指定していきます。
- ${__P(rampup,30)}
- ${__P(loop,10)}
サンプラーエラー後のアクション
負荷テスト途中にエラーが発生した場合の挙動についても設定を入れていきます。
ECサイトなどでは、商品が存在しない場合に購入処理まで実行しても意味がありません。シナリオに合わせて、エラー時の挙動を適切に入れていきましょう。
サンプラーエラー後のアクション | 概要 |
---|---|
続行 | エラーを気にせずテストを続行させます |
StartNextThreadLoop | 終了し次のループを開始します |
スレッド停止 | 該当スレッドを停止させます |
テスト停止 | 該当テストを停止させます |
StopTestNow | 即時でテストを停止させます |
次のループを開始させる設定を入れていきます。設定はスレッドグループのサンプラーエラー後のアクションのラジオボタンを選択するだけです。
リスナーの無効化
GUIはメモリ消費が大きいため、実際の負荷テストはCUIで実行する必要があります。テスト実行結果は実行時に指定するので、リスナーを無効化しておきます。
- リスナー選択->右クリック->無効
なお、実行時に出力指定したファイルを、あとからGUIで各リスナーへ読み込ませることが可能です。
CUIでの動作確認
CUIでの実行コマンド
シナリオ作成が完了したら、CUIで実行してみましょう。以下のコマンドで実行が可能です。
${JMeterインストールディレクトリ}/bin/jmeter -n -t scenario.jmx -l result.jtl -Jthread=1 -Jrampup=1 -Jloop=1
「-t」オプションにシナリオファイルを指定します。「-l」には結果出力用のファイル名を、「-J」には変数化したスレッド数を指定しています。
エラー回避設定
Windows環境のCUIでテスト実行してみたところ、次のようなエラーが出力されました。
... end of run
The JVM should have exited but did not.
The following non-daemon threads are still running (DestroyJavaVM is OK):
Thread[DestroyJavaVM,5,main], stackTrace:
Thread[AWT-Shutdown,5,system], stackTrace:java.lang.Object#wait
sun.awt.AWTAutoShutdown#run
java.lang.Thread#run
Thread[AWT-EventQueue-0,6,main], stackTrace:sun.misc.Unsafe#park
java.util.concurrent.locks.LockSupport#park
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject#await
java.awt.EventQueue#getNextEvent
java.awt.EventDispatchThread#pumpOneEventForFilters
java.awt.EventDispatchThread#pumpEventsForFilter
java.awt.EventDispatchThread#pumpEventsForHierarchy
java.awt.EventDispatchThread#pumpEvents
java.awt.EventDispatchThread#pumpEvents
java.awt.EventDispatchThread#run
その場合は、「bin/jmeter.properties」へ次の設定を追加することで回避できました。
対象ファイル:bin/jmeter.properties
jmeterengine.force.system.exit=true
まとめ
負荷テスト用の設定をしないと、正しい負荷をかけることができません。
スレッド数は変数化を行い、必要に応じて指定できるようにしておきましょう。また、Ramp-Up期間とタイマ設定は結果に大きく影響するパラメータです。設計段階でどのような値にしておくかを検討しておくとよいでしょう。エラー時の処理についても続行にしてしまうと、エラーが多発したさいに、結果が大きくぶれていってしまいます。
負荷テスト用に適切な設定を行い、より実践的な条件設定が重要です。
シナリオ作成入門シリーズで行ってきた技術的要素を習得することで、結構な範囲の負荷テストシナリオを作成することができると思います。実際にシナリオ作成をしてみてください。
~~~~~~~~~~~~~~~~~~~~~
~ JMeterの負荷テストシナリオ作成入門 ~
~~~~~~~~~~~~~~~~~~~~~
第1回:【負荷テスト】JMeterのシナリオ作成入門
第2回:JMeterのインストールと初期設定
第3回:HTTPプロキシサーバーを利用したベースシナリオの作成
第4回:動的パラメータを取り込み、エラーを解消させる
第5回:リファクタリング実施
第6回:入力パラメータを外部ファイルから読み込む
第7回:負荷テスト用の修正を実施
番外編:EC-CUBE4の環境構築方法
番外編:シナリオが正しく動作しないときの調査方法