JMeterで負荷テストのリクエスト送信が失敗したら、リトライする方法
はじめに
こんにちは、DevOps推進2グループの李です。現在進行中の案件はJMeterを使って、負荷テストスクリプトをメンテナンスしていますが、この案件で経験したJMeterでリトライ処理をシェアしたいと思います。
今回紹介したいリトライ処理は、レスポンスコードは200または204以外のコードが戻って来た際のリトライ処理です。もちろん他の判断条件下で実行することもできです。例えば検索結果が0件など、画面中に特定のエレメントが存在する際にも使用できますが。今回はレスポンスコードの判定を例として紹介します。
今回使用するJMeterバージョンはJMeter-5.4.3です。 https://jmeter.apache.org/download_jmeter.cgi
必要な知識
JMeterの基本操作
Javaプログラミング知識
この記事はJavaの書き方とJMeterのThread GroupかHTTP Requestの設定などに関する基本知識があることを想定します。
なぜリトライが必要なのか ?
負荷テストのシナリオはほとんどが単一ステップではなく、複数ステップのシナリオとなります。そして前段のシナリオと後続のシナリオは関連性があって、前段のステップに予想以外の結果が戻ってきたら、後続のステップも予想以外の結果になるでしょう。そのため、前段のステップはリトライ処理が必要と考えます。
実際に負荷テストを実施している時、サーバーに負荷がかかっているため、サーバーの反応が遅く、タイムアウトになることは少なくないです。この時リトライ処理に入って、リクエストをやり直すと、後続のステップも正常に実行できます。
実装する方法
では早速、リトライ処理の実装に入ります。先ずは「User Defined Variables」を追加して、変数retryTimesを追加します。この変数はリトライの上限回数です。その後はLoop ControllerとJSR223 PostProcessorを追加します。 テストプランのイメージは下図を参考にしてください。
各部品の機能は下記です。
User Defined Variables:変数を定義するところです。
Loop Controller:リクエストを繰り返すため、Loop Controllerが必要です。
HTTP Request:リクエストです。
JSR223 PostProcessor:リクエストが失敗した、リトライ処理のスクリプトを実装するところです。
上記の4つの部品の中で、一番重要なのはJSR223 PostProcessorです。この部品はリトライ処理のコードを書くところです。
JSR223 PostProcessorのコードは下記です。
String retryTimes = vars.get("retryTimes");
int conTimes = Integer.parseInt(retryTimes);
int runTimes = Integer.parseInt(vars.get('__jm__Loop Controller__idx'));
if (prev.getResponseCode() == '200' || prev.getResponseCode() == '204') {
ctx.setTestLogicalAction(ctx.TestLogicalAction.BREAK_CURRENT_LOOP);
if(runTimes>0){
log.info("リトライを実施したら、レクエルドが成功しました。");
}
}else {
if (runTimes < conTimes-1) {
prev.setIgnore();
if(runTimes==0){
log.info("レクエルドが失敗して、リトライ処理を開始します。");
}
}else{
log.info("レクエルド回数の上限に届きました。");
}
}
上記コードの解説:
retryTimesはUser Defined Variablesに定義しているリトライの上限回数を取得する意味です。conTimesはretryTimesを数値に変換します。
vars.get(“__jm__Loop Controller__idx”)はJMeterのLoopControllerのループ回数を表すインデックスの取得方法です。
ここでの注意点は、__jm__Loop Controller__idx中のLoop Controllerは部品名であり、部品名が変わると、この変数取得も合わせる必要があります。
条件の判定については、レスポンスコードが200または204の場合、ループをブレイクしてログを出します。それ以外の場合はリトライをして、最終のリトライ処理と最初のリトライ処理のログを出します。
注釈: ctx.setTestLogicalAction(ctx.TestLogicalAction.BREAK_CURRENT_LOOP); は外側のLoopControllerをブレイクするということです。Forループのbreakと同じ意味です。
まとめ
今回紹介したのは、リクエストのレスポンスコードが200または204以外の場合のリトライ処理です。コードの書き方はリクエストが成功したらブレイク処理です。
ここで注意しなければいけない点は、__jm__Loop Controller__idxのインデックスの取得部分に、部品名を合わせなければ動かないことです。
実際に負荷テストを実施する際に、インターネットの都合により、リクエストが失敗する可能性が低くはないので、リトライ処理は役に立つ技術であると思います。この技術を使うことによって、後続のリクエストには影響なくスムーズに実施できるようになります 。今まで経験した負荷テストでは、負荷をかけるだけで、リクエスト自体が成功するかどうかに注目をしていませんでした。今回初めてリクエストを成功させるため、リトライ処理を追加して実用的なスキルを共有することによって、業務が効率が上がることが期待できます。
________________________________