見出し画像

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を追加します。 テストプランのイメージは下図を参考にしてください。

各部品の機能は下記です。

  1. User Defined Variables:変数を定義するところです。

  2. Loop Controller:リクエストを繰り返すため、Loop Controllerが必要です。

  3. HTTP Request:リクエストです。

  4. 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のインデックスの取得部分に、部品名を合わせなければ動かないことです。

実際に負荷テストを実施する際に、インターネットの都合により、リクエストが失敗する可能性が低くはないので、リトライ処理は役に立つ技術であると思います。この技術を使うことによって、後続のリクエストには影響なくスムーズに実施できるようになります 。今まで経験した負荷テストでは、負荷をかけるだけで、リクエスト自体が成功するかどうかに注目をしていませんでした。今回初めてリクエストを成功させるため、リトライ処理を追加して実用的なスキルを共有することによって、業務が効率が上がることが期待できます。

関連記事: https://stackoverflow.com/questions/57666274/jmeter-retry-request-if-failed-or-responsecode-not-equal-to-200


________________________________

執筆者プロフィール:李 嘉興
前職で数年間ソフトウェア開発を経験しました、SHIFTに入社して自動化テストに関する経験が少ない中で毎日楽しんでやっています。更にダイエットしたいと思っても、自分の食欲をコントロールできず、何度も失敗している私です。