明日楽するために使えるようになりたい。JMeterの基本的な使い方。

Apache JMeter, 開発環境・ツール

こんにちは、ソリューション開発部の油井です。

皆様は負荷テストを行う時、どのツールをお使いでしょうか?JMeter、Load Impact、Gatlingなどいくつか思い浮かぶものがあるかと思います。

私は最近、プロジェクトにてJMeterを使用しました。JMeterはこれまで触れる機会がなかったため、シナリオ作成時にはグーグル先生にお伺いしつつ準備したものの、誤った設定をしてしまった場面もありました。

そのため、今回は反省を含め、JMeterの基本的な使い方(負荷テストを行うまでの手順)を記事にしたいと思います。また、これに加え、便利な機能や使い方を分かりやすく説明しているサイト様もあわせてご紹介させていただきます。

JMeterを初めて触るという方の力に少しでもなれれば幸いです。

JMeterとは

Apacheソフトウェア財団が開発している、Webシステムに代表されるクライアント・サーバシステムの負荷テストとパフォーマンスの計測を行えるツールです。対象となるサーバに対して指定した量のリクエストを送り、そのレスポンスを受け取る間のパフォーマンスを計測することによって負荷を検証します。

Apache製品であることやオープンソース、利用制限がないことから利用者が多いです。そのおかげで、作業するにあたり、分からないところがあった際にウェブで検索すると、解説サイトが多数存在しておりとても助かりました。

JMeterでテストを行う良さとしては、下記のようなものが挙げられます。(詳細は後述します)

  • シナリオテストを行うことができる
  • ブラウザで表示したページを記録し、どんなリクエストが投げられているか確認できる(テストにそのまま使える)
  • Cookieの維持ができる
  • リクエストとして送る内容について、細かい条件設定やパラメータの設定が可能
  • テスト結果をさまざまな形式で表示、出力できる
  • 返却されたレスポンスから値を取得して、利用することができる

インストール

JMeterのダウンロードはApacheの公式サイトから行うことができます。

インストールと起動の方法およびツールの各項目の詳細はこちらのサイトが分かりやすく説明されておりますので、ご参照ください。

負荷テストをやってみる

簡単な負荷テストの準備~実行をやってみたいと思います。

主な登場人物

テストシナリオを作成するにあたり、必ず使用する部品(JMeter上では「コンポーネント」と呼びます)をざっくりとご紹介したいと思います。

  • テスト計画
  • スレッドグループ
  • サンプラー
  • リスナー

それぞれの役割は下記のようになっております。

これらのコンポーネントのほかにも、さまざまな設定(たとえば、条件分岐など)を行うためのコンポーネントが存在しますが、ただ「特定のリクエストを送信して、レスポンスを受け取る」というようなテストでしたら、これだけで済みます。

JMeterの各コンポーネントと役割

実行までに必要な主な手順は下記になります。

  1. テスト計画の準備
  2. スレッドグループの追加
  3. サンプラーリスナーの追加
  4. リクエストの追加

簡単ではありますが、順を追って説明します。

テスト計画の準備

テスト計画とは、JMeterでテストを作成する際の最上位の概念です。ここにスレッドグループを追加することで、実行するテストのシナリオを作成することができます。

テスト計画は、JMeter起動時に新規作成状態のテスト計画が一つ用意されます。自分で作成する際は、File > Newメニューを選択すると作成することができます。

スレッドグループの追加・設定

スレッドグループとは、その配下に含められた一連のテストを実行するスレッド(ユーザ)のグループです。複数のユーザが同じ処理を行う場合を想像するとしっくりくるかと思います(デフォルトは、1スレッドです)。

追加は、テスト計画のアイコン上で右クリック > Add > Threads (Users) > Thread Group から行うことができます。

スレッドグループの追加・設定

サンプラーとリスナーの追加・設定

サンプラー

サンプラーとは、試験対象のサーバに対してリクエストを送信するコンポーネントです。今回はウェブサーバへHTTPリクエストを送信する想定なので、HTTP Requestのサンプラーを追加します。

追加は、スレッドグループで右クリック > Add > Sampler > HTTP Requestで行います。

サンプラーの追加・設定

もし、シナリオ上同じサーバに対して複数のリクエストを順に送る(いくつかの画面を順に遷移するなど)場合は、HTTP Requestより上にHTTP Request Defaultsの追加をおすすめします。

このコンポーネントは、リクエストの送信先となるデフォルトのサーバを指定するものです。これが設定されていると、以降のHTTP Requestサンプラーの設定項目を減らすことができます。

追加は、スレッドグループで右クリック > Add > Config Element > HTTP Request Defaults で行います。

サンプラーの追加・設定

なお、「1から作るのとかめんどくさー」と思われた方。

ご安心ください。JMeterには、プロキシサーバの役割を担い、ブラウザで遷移した際のリクエストを確認することができる機能があります。この機能で記録したリクエストをテストの一部に利用することができます。詳細は後述の「Tips」をご確認ください。

リスナー

リスナーは、負荷テストの実行結果をグラフ形式やツリー形式といった形式で閲覧することができるコンポーネントです。リスナーには上記だけでなく、さまざまな出力形式に対応したコンポーネントが用意されておりますので、こちらのサイトで詳細をご確認ください。

今回はツリー形式で送信したリクエストと、返却されたレスポンスを確認できるView Results Treeを追加しています。

リスナーの追加・設定

テストの実行

テストの実行は、画面上部の緑のボタンで行います。

テストの実行

同じテスト計画の中に複数のスレッドグループが存在する場合、上のスレッドグループの処理から順に実行されます。もし、一部のスレッドグループ(やリクエスト)のテストを実行されないようにしたい場合は、その処理を無効にする必要があります。

無効化は、無効にしたい処理の行で右クリック > Disableで行うことができます。

実行結果の確認

テストの実行結果は、上述で追加したリスナーから確認することができます(追加したリスナーによって表示される内容、形式は異なります)。下の画像はgoogleのデフォルトページへ送信したGETリクエストの結果です。

実行結果の確認

以上が基本的なテスト計画の作成方法です。

続いて、冒頭に申し上げたより便利にJMeterを使うための方法や、テストの際によく使うと思われる機能や説明しているウェブサイトの説明が分かりにくかったところ、「使える!」「もっと早く知りたかった…!」と思ったことをいくつか取りあげてみました。

Tips

ブラウザで遷移したページを記録し、リクエストの内容を確認する

JMeterには、プロキシサーバの役割を担い、ブラウザで遷移したページのリクエスト/レスポンスを記録できる機能があります。これを使うと、テストを作成する際、いちいちリクエスト先のサーバの情報や送信するパラメータの数や値を確認する必要がなくなり手数が減ります。

記憶させるために必要な手順の詳細は、こちらのサイトをご参照ください。設定が適切にできていると、遷移した情報が Recording Controller 配下に保存されます。

ブラウザで遷移したページを記録し、リクエストの内容を確認する

一連のテストが終わるまでセッション(Cookie)を維持させたい

ログイン機能など、ウェブページがセッションを活用している場合、一連のテストが終了するまでセッションを維持したいと思いますよね。

JMeterでは、デフォルトでは維持されませんので、維持させるためにConfig Elements > Cookie Manager を追加してください。

一連のテストが終わるまでセッション(Cookie)を維持させたい

Options の Clear cookies each iteration? のチェックボックスをオンにすると、スレッドグループのループごとにCookieが破棄されるようになります。また、あらかじめ保持させたい値がある場合は、下部の User-defined Cookies に追加すると、保持させることができます。

レスポンスから値を取得し、後続の処理で使いたい

ECサイトの購入フローなど、複数の画面を遷移するテストをする場合、前のリクエストで返却されたレスポンスから値を取得したい!となることがあるかと思います。そのような場合は、Post Processors > Regular Expression Extractor を利用して、レスポンスのHTMLから値を取得します。

Regular Expression

レスポンスから値を取得するために使用する正規表現を設定します。取得した値は ${変数名} で利用することができます。

「正規表現が正しく動作するか確認したい!」という方は、当該レスポンスが得られるリクエスト動作確認まで終わっているようでしたら、前もって確認することもできます。

確認方法は、リスナーとしてView Results Tree を追加し、こちらで値を取得したい画面へのリクエストを送信してください。実行したリクエストを選択し、 画面左部のドロップボックスを RegExp Tester に変更し、Regular expression欄に作成した正規表現を入力すると、期待した値を取得できるか確認することができます。

If/While条件のループがしたい

If/Whileといった条件は、Logic Controller から追加することができます。これらのコントローラを使用する場合、判定式を指定してください。判定式の記述方法はこちらを参照してください。判定式がtrueの場合は、内側の処理が実行されます。

なお、If/Whileコントローラの判定式を記述する際、注意する点がひとつあります。それは、If Controller では、判定式はデフォルトとしてJavaScriptの式の判断されますが、While Controller ではJavaScriptに限らず様々な関数を利用することができます。そのため、同じJavaScriptでの判定を期待した式でも、記述方法が異なります。While Controllerの詳しい使い方は、こちらをご参照ください。

タイマーを使って時間差攻撃がしたい

Add > Timer で各種タイマーを追加することができます。タイマー各種の詳細はこちらを参照してください。

今回、 Gaussian Random Timer(ガウス乱数タイマー)を使用したのですが、プロパティを誤解してしまったため、復習も兼ねてご説明したいと思います。

タイマーを使って時間差攻撃がしたい

Deviation (in millseconds)

Constant Delay Offsetに対し、プラスマイナスに分散される範囲(ミリ秒)を指定します。

Constant Delay Offset (in millseconds)

固定の待機時間(ミリ秒)を指定します。
Constant Delay Offsetに5秒、Deviationに2秒を指定した場合、±~2秒が毎回ランダムで追加され、テスト全体で平均5秒の間隔になるようタイマーが動作します。

カウンター変数が欲しい

Config Element > Counter から追加することができます。
複数スレッド(ユーザ)を設定している場合、通常だとすべてのスレッド共通でインクリメントされます。ユーザごとにインクリメントを制御したい場合は、下部の Track counter independently for each user のチェックボックスをオンにしてください。

カウンター変数が欲しい

テスト計画ごとにユニークな値を設定したい

たとえば、処理の中で「いつテストを行ったか」というのが分かるようにしたい。そんな時は、そのテスト計画全体で使用可能な変数を設定したいと思いますよね。そのような時は、Test Plan の User Defined Variables で設定します(Config Element > User Defined Variablesの追加でも同様のことができます)。

同時実行するスレッド(ユーザ)の数を増やしたい

実行するスレッド数(ユーザ数)を増やしたい場合は、Thread Group の Thread Properties を設定します。

同時実行するスレッド(ユーザ)の数を増やしたい

Number of Threads (Users)

スレッド数(ユーザ数)を指定します。

Ramp-Up Period (in seconds)

すべてのスレッドを実行するのに必要な時間(秒)を指定します。

10スレッドに対し、この値を100と設定していると、100 ÷ 10 = 10 となり、10秒間隔に新しいスレッドが実行されることになります。この概念を最初勘違いしており、「思ったように動かない…」となったのであえて記述させていただきました。

Loop Count

各スレッドの実行回数を指定します。詳細は、こちらの説明を参照してください。

ユーザごとに別のパラメータを設定してテストしたい

ユーザごとにパラメータを用意したい場合は、目的に応じて下記のいずれかを使います。

コンポーネント利用目的
Pre Processors > User Parameters特定の処理でのみ必要なパラメータを設定したい
(ログインユーザ名/パスワードなど)
Config Element > User Defined Variablesスレッドグループ全体で利用したいパラメータを設定したい
(複数ユーザの同時使用を検証する際に各処理で使用したいIDなど)

変数および値の追加は下部の Add Variable、ユーザの追加は Add User から行います。

なお、前項でご説明したスレッド数(ユーザ数)より設定された値の数が少ない場合、下記のように、最後まで順に参照した後User_1の値に戻ります。

例)スレッド数:5、値の数:2

条件スレッド#参照する値
スレッド数 > 値が設定されたユーザ数1User_1
2User_2
3User_1
4User_2
5User_1

テスト結果をファイル出力したい

テスト結果はテキストファイルに出力することができます。

ファイルに出力したい場合は、追加したリスナーをクリックし、上部に表示される Write results to file / Read from file 欄に出力先のファイル名を指定してください。

テスト結果をファイル出力したい

テストの実行日時を取得して使いたい

実行日時の取得は、${__time(HMS)}といった関数を使用します。この関数では、HHmmss形式で時分秒を取得することができます。

他にもyyyyMMdd形式で取得できる関数など用意されておりますが、カスタマイズした形式での出力も可能のようです(私は試しておりませんが…)。

詳細はこちらでご確認ください。

各変数にどんな値が入っているか確認したい

準備したパラメータにちゃんと値が入っているか、どんな値が入っているか確認した場合は、Sampler > Debug Samplerを使用します。

前のリクエストで返却されたレスポンスから取得した値がちゃんと変数にセットされているか、カウンターの値がちゃんとインクリメントされてるかなどの場面で有用です。

値の確認が不要になった場合は、右クリック > Disableで無効化することもできます。

いくつも処理が並んでて見づらいからまとめたい

Windows Explorerでいう「フォルダ」みたいな概念として、一部のものをまとめたい時は、Logic Controller > Simple Controllerを追加します。

これを使うと、触る必要がない処理をまとめて畳めるため、分別として分かりやすいですし、スレッドグループ全体を眺めた際にスッキリします。(笑)

最後に

JMeterを初めて触る方向けに、基本的なテスト計画の作成方法とそれに使えそうなTipsをいくつかご紹介させていただきました。

が、1点注意があります。
それは「負荷テストを行う際は、コマンドラインから実行すること」です。

GUIからテストを実行してしまうと、GUIの描画、処理能力が処理時間に影響してしまい、テスト自体の正確な実行時間を計測できないためです。

「最後にそれ言うのかよ!」と思われた方、すみません。実は、私もGUIから実行してしまっておりました。ので反省を含め、ここに記載させていただきます。詳細および実行方法につきましては、こちらをご一読ください。

また何かしくじった時には、しくじり先生よろしくこちらに書こうと思います。

  • 株式会社アークシステムの来訪管理・会議室予約システム BRoomHubs
  • 低コスト・短納期で提供するまるごとおまかせZabbix