JMeterとAzure Load Testingでお手軽性能テスト

## はじめに
この記事は [NTTコムウェア AdventCalendar 2023](https://qiita.com/advent-calendar/2023/nttcomware) 23日目の記事です。

NTTコムウェア2020年入社社員の辻です。
入社当初は海外パッケージ製品を利用したサービス開発に従事しておりましたが、現在はキャリアデザインを促進するアプリケーションの開発に従事しております。

業務で実際に性能テストを実施する機会があったため、備忘録を兼ねて利用したツール等をまとめておきます。
この記事では、JMeterとAzure Load Testingを使用した性能テストの実施方法について記載していきます。
初めて性能テストを行うといった方の参考になれば幸いです。

## 実行環境
この記事では下記の実行環境を前提として記載を行っています。

:::note info
- OS: `Windows Server 2019 Datacenter`
- バージョン: `1809`
- JavaVersionString: `1.8.0_391`
- JMeterVersion: `5.6.2`
:::

## 性能試験とは
> 性能テストとは、機器やソフトウェア、システムのテスト（試験）の一種で、要件を満たす性能が出るかどうかを確かめるもの。実際と同じように動かしてみるテストであるため、ほとんどの場合は開発の最終段階に近い工程で実施される。

- 引用: [性能テスト（パフォーマンステスト）とは - 意味をわかりやすく - IT用語辞典 e-Words](https://e-words.jp/w/%E6%80%A7%E8%83%BD%E3%83%86%E3%82%B9%E3%83%88.html)

https://e-words.jp/w/%E6%80%A7%E8%83%BD%E3%83%86%E3%82%B9%E3%83%88.html

上述の通り、性能テストとは非機能要件として定めている性能に関する項目が実際に満たされているのかを確認するテストとなります。
そのため、事前に非機能要件を定めている必要がありますが、本記事では割愛します。
参考までに、IPAから出されている非機能要求グレードのページを紹介しておきます。

- 参考: [システム構築の上流工程強化（非機能要求グレード）紹介ページ | アーカイブ | IPA 独立行政法人 情報処理推進機構](https://www.ipa.go.jp/archive/digital/iot-en-ci/jyouryuu/hikinou/ent03-b.html)

https://www.ipa.go.jp/archive/digital/iot-en-ci/jyouryuu/hikinou/ent03-b.html

また、性能テストの計画から実施と実施後のチューニングなどの流れについて知るには下記の記事がとても参考になったため紹介しておきます。

- 参考: [オンライン性能テスト概論 #チューニング - Qiita](https://qiita.com/s9910553/items/ca3dae561489844da646)

https://qiita.com/s9910553/items/ca3dae561489844da646

## 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 - Apache JMeter™](https://jmeter.apache.org/)

https://jmeter.apache.org

公式ページでも記載されているように、JMeterはJavaのみで構成された性能テストを実行できるアプリケーションです。
GUIでのテストシナリオの設計やテスト結果の視覚化などの機能が具備されており、初めての方でも直感的に使用できるアプリケーションです。

## Azure Load Testingとは
> Azure Load Testing は、大規模な負荷を生成できるフル マネージドのロード テスト サービスです。 サービスは、アプリケーションがどこにホストされているかにかかわらず、そのトラフィックをシミュレートします。 開発者、テスト担当者、品質保証 (QA) エンジニアは、それを使って、アプリケーションのパフォーマンス、スケーラビリティ、または容量を最適化できます。

- 引用: [Azure のロード テストとは | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/load-testing/overview-what-is-azure-load-testing)

https://learn.microsoft.com/ja-jp/azure/load-testing/overview-what-is-azure-load-testing

公式ページでも記載されているように、Azure Load TestingはAzureで利用できるフルマネージドのサービスです。
手元で複数台のクライアントを用意したり、性能テストの実行時にクライアント側のネットワークがボトルネックとなったりすることを気にせずに利用できる点がメリットとして挙げられます。

## JMeterの使い方
JMeterのレコーディング機能を利用して性能テストのシナリオを作成する方法を紹介します。
1. [公式サイト](https://jmeter.apache.org/download_jmeter.cgi)からJMeterをダウンロードする
![jmeter_download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/de44426b-59df-bc46-4f77-ead6a4fd9962.png)
1. 任意の場所に圧縮ファイルを展開する
1. `bin/jmeter.bat`を実行する
1. File -> Open -> `bin/templates/recording.jmx`を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/99930cd9-ac1f-0383-fa2e-b583d5fabee2.png)
1. 左のツリーの`HTTP(S) Test Script Recoder`を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/d1d4b3b5-f16e-53f3-84f3-f0d0161c7d94.png)
1. `Start`ボタンを押下する
1. `HTTP Sampler settings`に設定値をセットして`Set counter`を押下する
    1. `Transaction name`: 任意の値(ページ名などを指定すると後から加工しやすい)
    1. `Naming scheme`: Prefix
    1. `counter start value`: 任意の値(カウンターのスタート値)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/527fc985-e8c8-2c54-4c8d-558824d4869c.png)
1. `bin/ApacheJMeterTemporaryRootCA.crt`を信頼されたルート証明機関としてインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/0e32cf0f-60e4-53b0-53e9-53169da343a8.png)
1. Windowsの設定 -> ネットワークとインターネット -> プロキシで手動プロキシを設定して保存する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/fb9699ee-a82d-ed5a-173f-7796aa12e418.png)
1. 性能テストのシナリオ相当の操作をブラウザ上で実行する
1. `Stop`ボタンを押下する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/527fc985-e8c8-2c54-4c8d-558824d4869c.png)
1. 左のツリーの`Recording Controller`配下に作成された`HTTP Request`を確認する
1. 性能テスト実施時には不要な`HTTP Request`を削除する
1. 左のツリーの`Thread Group`を選択する
1. `Thread Propeties`に設定値をセットする
    1. `Number of Threads(users)`: 任意の値(同時に実行したいスレッド数を指定する)
    1. `Ramp-up period(seconds)`: 任意の値(すべてのスレッドが立ち上がるまでに使用する秒数を指定する)
    1. `Loop Count`: Infinite(今回は任意の秒数負荷をかけるために無限ループを指定する)
    1. `Specify Thread lifetime`: チェックを入れる(各スレッドの寿命を指定するためのフラグを有効にする)
    1. `Duration(seconds)`:任意の値(負荷をかけ続けたい秒数を指定する) 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/74e569ad-3c41-1797-9da3-000194d0f604.png)
1. 左のツリーの`Thread Group`を右クリック -> Add -> Timer -> Constant Throughput Timerを追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/058dc7a5-30bc-d0cb-55c3-28ffae3774c1.png)
1. 左のツリーの`Constant Throughput Timer`を選択する
1. `Constant Throughput Timer`に設定値をセットする
    1. `Target throughput(in samples per minute)`: 任意の値(1分間に達成されるべきスループット)
    1. `Calculate Throughput based on`: all active threads in current thread group (shared)(スループットの計算ベースにする範囲を指定する)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/d4620a11-330c-1921-7c31-d5e4950c638c.png)
1. File -> Save Test Plan as -> 任意の名前を付けたjmxファイルを保存する

## Azure Load Testingの使い方
JMeterで作成したjmxファイルを使って、Azure Load Testingから性能テストを実施するページに対して負荷をかける方法を紹介します。
1. Azure Load Testingサービスのリソースを作成する
    1. 基本
![azureloadtesting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/7952dd21-a4ae-6c5b-b297-d91ed77027df.png)
        1. プロジェクトの詳細
            1. `サブスクリプション`: 任意のサブスクリプションIDを選択
            1. `リソースグループ`: 任意のリソースグループを選択
        1. インスタンスの詳細
            1. `名前`: 任意の名前を入力
            1. `リージョン`: 任意のリージョンを選択
    1. Encryption
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/349983c7-49c4-9855-3206-0ab56bb4cbd3.png)
        1. `暗号化の種類`: 任意の暗号化方式を選択
    1. タグ(必要に応じて任意のタグを登録)
    1. 確認および作成(設定したパラメータを確認したうえで作成を実行)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/cac01cae-f18b-23b7-b607-0ec239d2402e.png)

1. 作成したAzure Load Testingのリソース上でテストを作成する
![azureloadtesting_create_test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/e31fa0e8-03e9-ec49-e541-a2022afdced1.png)
    1. Basics
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/724c0de5-e199-ef95-dcca-c1bab15743d8.png)
        1. `テスト名`: 任意のテスト名を入力
        1. `テストの説明`: 任意のテストの説明を入力
        1. `作成後にテストを実行する`: チェックを入れておく
    1. テスト計画
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/f2263ef3-35c3-128e-8f34-9c3fc2a87ddc.png)
        1. `ファイルの選択`: JMeterの利用で作成した jmxファイル をアップロードする
    1. パラメータ(必要に応じて任意のパラメータを設定)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/37c5e390-2f13-b9fb-a916-ab79d7f7aed4.png)
    1. 読み込み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/1f8f7fc7-d81e-b267-3a0a-fd51cfa29482.png)
        1. `エンジン インスタンス`: 掛けたい負荷によって任意のインスタンス数を設定
        1. `テスト トラフィック モードの構成`: 公開用を選択(※ 接続元IPアドレス等による制限をかけている場合は `非公開` を選択する必要有)
    1. テスト抽出条件
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/7ce3548b-3a24-7abb-3491-4282c29e7a48.png)
        1. `自動停止テスト`: 有効化を選択
        1. `エラーの割合`: 任意の値を入力(デフォルト90)
        1. `時間枠(秒)`: 任意の値を入力(デフォルト60)
    1. 監視(必要に応じて設定)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/0ecf72f0-1e95-bdc5-6d4a-345213e76fdd.png)
    1. 確認および作成(設定したパラメータを確認したうえで作成を実行)
1. Azure Load Testingの実行結果の確認
![azureloadtesting_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622795/1ff58bda-3ccd-5dcb-b55f-04e3e9949d2f.png)
    1.  `読み込み`: 総リクエスト数
    1.  `期間`: 負荷がかかっていた時間
    1.  `応答時間`: レスポンスにかかった時間(90パーセンタイル)
    1.  `エラーの割合`: レスポンスが正常でなかった割合
    1.  `スループット`: 1秒に処理したリクエスト数
等をグラフを交えて確認できます

## おわりに
JMeterとAzure Load Testingを使用した性能テストの紹介をしました。
実際にサービスをリリースする前に性能テストを通過しておくことで、非機能要件として定めていた項目が達成されているかを確認できます。
また、達成できていなかった場合にはサービスを構成するリソースも合わせて確認することでボトルネックとなっている箇所を特定し、その後の改善に繋げられます。

記載されている会社名、製品名、サービス名は、各社の商標または登録商標です。 
画面等、記載の内容は2023/12時点のものとなります。