eviry tech & service blog

「株式会社エビリー」の社員ブログです。弊社では、クラウド型動画配信サービス「millvi」、ソーシャル動画データ及び分析サービス「kamui tracker」、YouTube総合メディア「かむなび」を開発・提供しています。https://eviry.com/

JMeter による負荷試験の実施手順

こんにちは。 株式会社エビリーmillvi 開発チームでエンジニアをしております。 井上と申します。

millvi は動画配信のサービスであり、時には過去の実績を超えた要件( アクセス数 )で配信したい、といったお客様もいらっしゃいます。 そうした場合になんの検証もせずに本番に望むわけにはいきませんので、事前検証として負荷試験を実施することで、本番運用に向けての情報収集を行います。

はじめに

millvi では負荷試験の実施に JMeter を使っています。 本稿では JMeter を使った負荷試験の実施手順について扱います。

環境

バージョン 備考
macOS Catalina 10.15.7
JMeter 5.4 2020/12/07 現在の ダウンロードサイト から
Java( openjdk ) 11.0.9 2020-10-20 java --version で確認

JMeter とは

公式 から抜粋

The Apache JMeter™ application is open source software, a 100% pure Java application designed to load test functional behavior and measure performance. It was originally designed for testing Web Applications but has since expanded to other test functions.

Apache JMeter™ アプリケーションはオープンソースのソフトウェアで、機能動作をロードテストし、パフォーマンスを測定するために設計された100%純粋なJavaアプリケーションです。 元々はWebアプリケーションのテスト用に設計されていましたが、他のテスト機能にも拡張されています。

上記の通りパフォーマンス計測のための Java アプリケーションである。

ダウンロード

JMeter のダウンロードは下記リンクから行える。

0000_download.png

インストール

インストールはダウンロードしたバイナリを解凍し、任意のディレクトリに配置するだけ。 今回は次のように配置した。

$ pwd
/Users/hoge/workspace                           # workspace は作業用ディレクトリとして元々作成済み
$ mkdir performance                             # 負荷試験用のディレクトリを掘って
$ mv ~/Download/apache-jmeter-5.4 ./performance # どこにバイナリを配置する
$ cd performance/
$ ls -l
total 0
drwxr-xr-x@ 12 hoge  staff  384 12  6 20:38 apache-jmeter-5.4

起動

起動は次のコマンドを実行する。

$ cd apache-jmeter-5.4/
$ sh ./bin/jmeter       # これで JMeter の GUI が起動する

注意事項

起動にあたり以下が設定されていることが前提条件となる。そうでないと起動エラーとなる。

  • jdk の PATH が通っていること
  • JAVA_HOME の環境変数が設定されていること

起動エラーの例

$ sh ./bin/jmeter
Unable to find any JVMs matching version "(null)".
No Java runtime present, try --request to install.
Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
At least one of these environment variable is needed to run this program

負荷試験の実施

本記事で扱う負荷試験の要件

以下の要件に対して負荷試験を実施する。

  • Web Server へのアクセス負荷を検証する
    • プロトコルは https
    • サーバ名は hogehoge.com
    • HTTP メソッドは GET
    • アクセス先 PATH は test-hoge/hoge.m3u8
  • リファラが設定されている
    • リファラは https://cdn.test-hoge.com/hoge.html
  • 負荷
    • アクセス数 / 秒 がどこまで正常に処理できるか

テスト計画の作成と設定

というわけで、上記の要件に沿うように JMeter で行う負荷試験のシナリオを設定していく。

JMeter は起動時、Test Plan という項目が左側ペインにポツンとあるだけなので、これを元にテスト計画を作っていく。

1. 初期起動時の状態

0001_boot.png 起動時はご覧の通りなにも設定されていない。TestPlan という項目があるだけ。 これに対してテスト要件にあわせて設定を追加していく。

2. Thread Group の追加と設定

0201_add_thread_group.png TestPlan を選択した状態で右クリック ( mac なら 2 本指でクリック ) するとメニューが表示されるので、Add -> Threads(Users) -> Thread Group) の順で Thread Group を追加する。

0202_thread_group_settings.png 今回実施する負荷試験で重要な設定内容となるのが下記表の 3つ。 ( Name は任意。デフォルトのままでも良い )

項目 説明 備考
Number of Threads (users) スレッド数の設定 各スレッドは 他のテストスレッドとは完全に独立 してテスト計画を実行する.
複数のスレッドを使用してサーバーアプリケーションへの 同時接続をシミュレート する.
Ramp-up period (seconds) ランプアップ期間の設定 選択したスレッドの数だけ「ランプアップ」するのにかかる時間を JMeter に通知する.

例)
10個のスレッドを使用し、ランプアップ期間を100秒とした場合、10個のスレッドが全て立ち上がるまでに100秒かかる.
各スレッドは、前のスレッドが開始されてから10(100/10)秒後に開始される.
スレッドが30個あり、ランプアップ期間が120秒の場合、各スレッドは4秒遅れて開始される.

ランプアップはテスト開始時の作業負荷が大きくなりすぎないように十分な長さが必要.

Ramp-up = スレッドの数 でスタートし、必要に応じて上下に調整 する.
Loop Count テストの実行回数を設定する

キャプチャした画像を例にとると、このケースでは「1つのスレッドを1秒間に処理する。各スレッドはシナリオを一回だけ実行する」、つまり「1秒間に一回のアクセスがサーバに対して行われる」というシナリオになる。

秒あたりのアクセス負荷を上げたい場合、これら 3つの項目を調整 していくのだが、ここで注意点が一つ。

「秒あたりのアクセス負荷を上げるんだったら、スレッド数とランプアップ期間で調整すれば実行回数まで考えなくても良いよね」といった感じで設定すると、テストを実行する PC の負荷が上がってテストが失敗することがある。

[参考までに]

本稿での設定とは別に次の設定をして試験を実施したところ失敗した。

Number of Threads (users) Ramp-up period (seconds) Loop Count Reesult 試験要件
4,000 1 1 動かなくなった 4,000アクセス / 1sec

次の設定だと成功した。

Number of Threads (users) Ramp-up period (seconds) Loop Count Reesult 試験要件
400 100 1,000 OK 4,000アクセス / 1sec

という感じで、何度も繰り返して恐縮だが 3つの項目を調整 してテストを実行する環境の負荷にも目を向けつつ、テストされる側の負荷を上げていく。

3. HTTP Request の追加と設定

公式 >3.1 Thread Group には次の記載がある。

Thread group elements are the beginning points of any test plan. All controllers and samplers must be under a thread group. Other elements, e.g. Listeners, may be placed directly under the test plan, in which case they will apply to all the thread groups. As the name implies, the thread group element controls the number of threads JMeter will use to execute your test.

スレッドグループの要素は、テスト計画の最初のポイントです。すべてのコントローラとサンプラーはスレッドグループの下になければなりません。リスナーなどの他の要素は、テスト計画の直下に配置することもできますが、その場合はすべてのスレッドグループに適用されます。その名の通り、スレッドグループ要素は、JMeter がテストを実行するために使用するスレッドの数を制御します。

ということで、以降に出てくる設定は全て Thread Group 配下、もしくは更に下に要素を追加して行っていく。

ここでは試験対象となるアクセス先の設定を行う。

0301_add_http_request.png Thread Group を選択した状態で右クリック ( mac なら 2 本指でクリック ) するとメニューが表示されるので、Add -> Sampler -> HTTP Request の順で HTTP Request を追加する。

0302_http_request_settings.png 次の設定項目を実際の環境に合わせて設定する。( Name は任意。デフォルトのままでも良い )

項目 説明 備考
Protocol アクセスする際のプロトコルを設定する
Server Namse or IP アクセス先のサーバ名、もしくは IP アドレスを設定する
メソッド アクセス時のメソッドを設定する
Path アクセス先のパスを設定する Server Name or IP で指定した内容に絡む

今回の設定例ならば https://hogehoge.com/test-hoge/hoge.m3u8 に対して GET メソッドでアクセスする という意味になる。

4. HTTP Header Manager の追加と設定

今回の試験では リファラが設定されている ことが要件に挙がっているので、HTTP Header にリファラを設定する。

0401_add_http_header_manager.png HTTP Request を選択した状態で右クリック ( mac なら 2 本指でクリック ) するとメニューが表示されるので、Add -> Config Element -> HTTP Header Mamnager の順で HTTP Header Mamnager を追加する。

0402_http_header_manager_settings.png Add ボタンをクリックし、refer 情報を設定する。( Name は任意。デフォルトのままでも良い )

項目 説明 備考
referer 現在リクエストされているページへのリンク先を持った直前のウェブページのアドレス

今回の設定例ならば https://hogehoge.com/test-hoge/hoge.m3u8 のリファラとして https://cdn.test-hoge.com/hoge.html を設定した という意味になる。

5. Aggregate Report の追加と設定

上記までが試験実施のための設定。 ここでは試験実施後の結果をみるために Aggregate Report を追加する。

0501_add_aggregate_report.png Thread Group を選択した状態で右クリック ( mac なら 2 本指でクリック ) するとメニューが表示されるので、Add -> Listener -> Aggregate Report の順で Aggregate Report を追加する。

0502_aggregate_report_settings.png Filename にレポート保存時のファイル名を設定する。( Name は任意。デフォルトのままでも良い )

実行( とクリア )

0601_command.png 試験の実行は ピンク枠 のどちらかをクリックする。

  • 左側: Start
  • 右側: Start no pauses

試験結果のクリアは オレンジ枠 のどちらかをクリックする。

  • 左側: clear
  • 右側: Clear All

実行前のファイル確認

試験実行前に report.csv が出力されていないことを確認する。

$ ls -l
total 3785128
-rw-rw-r--@   1 hoge  staff       15631  2  1  1980 LICENSE
-rw-rw-r--@   1 hoge  staff         172  2  1  1980 NOTICE
-rw-r--r--@   1 hoge  staff        5523 12  7 19:47 PerformanceTest.jmx
-rw-rw-r--@   1 hoge  staff       10089  2  1  1980 README.md
drwxr-xr-x   12 hoge  staff         384 12  7 19:47 backups
drwxrwxr-x@  44 hoge  staff        1408 12  6 23:32 bin
drwxr-xr-x@   6 hoge  staff         192  2  1  1980 docs
drwxrwxr-x@  22 hoge  staff         704  2  1  1980 extras
-rw-------    1 hoge  staff  1936927555 12  7 15:33 java_pid57152.hprof
-rw-r--r--    1 hoge  staff      140194 12  7 19:47 jmeter.log
drwxrwxr-x@ 104 hoge  staff        3328  2  1  1980 lib
drwxrwxr-x@ 104 hoge  staff        3328  2  1  1980 licenses
drwxr-xr-x@  19 hoge  staff         608  2  1  1980 printable_docs

実行後のファイル確認

試験実行前に report.csv が出力されていることを確認する。

$ ls -l
total 3785136
-rw-rw-r--@   1 hoge  staff       15631  2  1  1980 LICENSE
-rw-rw-r--@   1 hoge  staff         172  2  1  1980 NOTICE
-rw-r--r--@   1 hoge  staff        5523 12  7 19:54 PerformanceTest.jmx
-rw-rw-r--@   1 hoge  staff       10089  2  1  1980 README.md
drwxr-xr-x   12 hoge  staff         384 12  7 19:47 backups
drwxrwxr-x@  44 hoge  staff        1408 12  6 23:32 bin
drwxr-xr-x@   6 hoge  staff         192  2  1  1980 docs
drwxrwxr-x@  22 hoge  staff         704  2  1  1980 extras
-rw-------    1 hoge  staff  1936927555 12  7 15:33 java_pid57152.hprof
-rw-r--r--    1 hoge  staff      141450 12  7 19:54 jmeter.log
drwxrwxr-x@ 104 hoge  staff        3328  2  1  1980 lib
drwxrwxr-x@ 104 hoge  staff        3328  2  1  1980 licenses
drwxr-xr-x@  19 hoge  staff         608  2  1  1980 printable_docs
-rw-r--r--    1 hoge  staff         311 12  7 19:54 report.csv

出力された csv ファイル( report.csv )

試験結果は report.csv で出力するよう設定したので、テキストファイルからも確認できる。

timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect
1607303084226,47,HTTP Request,200,OK,Thread Group 1-1,text,true,,584,215,1,1,https://hogehoge.com/test-hoge/hoge.m3u8,47,0,38

JMeter 上でのレポートの確認

Aggregate Reportから試験結果の統計情報を見ることができる。 0701_aggregate_report.png それぞれの値の意味は次の通り。

カラム 意味 備考
Label 試験を実施したテストケースのラベル HTTP Request のみ.
3. HTTP REQUEST の追加と設定 で設定した Name がこれ
Sample 試験の実行回数 Number of Threads と Ramp-up period と Loop Count の値による
Average 実行結果の平均値
Median 実行結果における中央値 テストの50%がこの時間以上かかっていないことを示す
90% Line 実行結果の 90% の集合 90%のサンプルはこの時間以上かかっていないことを示す.
10% はこれと同じくらいの時間がかかった
95% Line 実行結果の 95% の集合 95%のサンプルはこの時間以上かかっていないことを示す.
5% はこれと同じくらいの時間がかかった
99% Line 実行結果の 99% の集合 99%のサンプルはこの時間以上かかっていないことを示す.
1% はこれと同じくらいの時間がかかった
Min 実行完了までの最短時間
Maximum 実行完了までの最長時間
Error % エラー発生率
Throughput スループット 時間単位(秒、分、時間)で処理したリクエストの数.
最初のサンプルの開始から最後のサンプルの終了までの時間で計算される.
スループットが大きいほど良い.
Received KB/Sec 受信量 実行中にサーバーからダウンロードされたデータ量.
-> キロバイト/秒で測定したスループット.
Sent KB/Sec 送信量 実行中にサーバーに送ったデータ量.
-> キロバイト/秒で測定したスループット.

なお、テーブルに表示されている結果は画面下部の Save Table Data から csv 出力することもできる。 下記キャプチャは Save Table Data クリックで表示されたダイアログ。デフォルトで aggregate.csv というファイル名で保存するようになっている。 0702_aggregate_report_save.png 出力した csv の中身は以下の通り。

$ cat aggregate.csv
Label,# Samples,Average,Median,90% Line,95% Line,99% Line,Min,Max,Error %,Throughput,Received KB/sec,Sent KB/sec
HTTP Request,1,328,328,328,328,328,328,328,0.000%,3.04878,1.71,0.66
TOTAL,1,328,328,328,328,328,328,328,0.000%,3.04878,1.71,0.66

CUI での実行

テスト計画が作成されていることが前提だが、CUI からも JMeter は実行できる。 実行時のコマンドは以下の通り。

$ ./jmeter -n -t PerformanceTest.jmx # PerformanceTest.jmx はこれまで設定してきたシナリオファイル

なお JMeter は GUI から実行すると、それだけで実行マシンのリソースを余計に消費するので、CUI から実行するほうが望ましいとのこと。 公式 > 1.0.2 Load Test running には次のように書かれている。

Don't run load test using GUI mode !

というわけで設定ファイルを作って試行できたら、実際の負荷試験は CUI から実行するのが良い。

CUI でのコマンドオプションは下記を参照。

まとめ

  • Thread Group では次の 3つの項目を調整して、テストを実行する環境の負荷にも目を向けつつ、テストされる側の負荷を上げていく
    • Number of Threads (users)
    • Ramp-up period (seconds)
    • Loop Count
  • スレッドグループの要素はテスト計画の最初のポイントであり、すべてのコントローラとサンプラーはスレッドグループの下に設定する
  • テストの実行は GUI ベースではなく CUI ベース が望ましい

参考

公式

その他

インストール〜テスト実施

Aggregate Report