Web負荷テストツールの紹介（JMeter・AWS分散負荷テストソリューション）

# はじめに
社内向けにWebサイト・Webシステムの負荷テストツールであるJMeterとAWS分散負荷テストソリューションの基本的な使い方をまとめた資料を作成したのですが、どちらも汎用的なツールなのでQiitaにも投稿することにしました。
メモ的な要素が強いので、画像が少なくツールの説明としてはあまり優しくありませんが、そのあたりはご了承ください。

# JMeterの使い方
## インストール
以下のWebサイトで、Binariesのzipファイルをダウンロード＆解凍  
[Apache JMeter - Download Apache JMeter](https://jmeter.apache.org/download_jmeter.cgi)   

![jmeterinstall.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2528939/8cb9172d-a941-7633-3ec2-c08f093f4b4d.png)

## 起動
JMeterを展開したフォルダ/binにあるjmeter.batを実行
## 表示言語の変更
OptionタブのChoose LauguageからJapaneseを選択  
再起動時に英語に戻ってしまう場合は、JMeterを展開したフォルダ/binにあるjmeter.propertiesに以下を追記  
```
#language=en
 language=ja
```
## 外観の変更
オプションタブのルック＆フィールで選択可能  
個人的には「Windows」がおすすめ
## 基本的なシナリオの作成（google.co.jpにGETリクエストを送信）
### 1. スレッドグループの作成
「テスト計画」を右クリック  
追加 > Threads(Users) > スレッドグループ を選択
### 2. スレッドグループの設定
スレッドグループはシミュレーションの単位

スレッド数、Ramp-Up期間（秒）、ループ回数  を設定する  
Ramp-Up期間は負荷がピークに達するまでの時間。  
Ramp-Up期間まで徐々に負荷をかけていく。  
負荷をかける場合はこれらの値を変更するが、今回はデフォルト値のままにする。  
**※公開されているWebサイト・Webシステムに負荷をかけないこと※**
### 3. リスナーの作成
リスナーはシナリオの実行結果を表示する

「テスト計画」を右クリック  
追加 > リスナー > 結果をツリーで表示 を選択
### 4. HTTPリクエストの作成
HTTPリクエストにシナリオで送信するリクエストの内容を設定する

「スレッドグループ」を右クリック  
追加 > サンプラー > HTTPリクエスト を選択
### 5. HTTPリクエストの設定
|  設定項目       |  設定内容  |
| ---------------- | ---- |
|プロトコル      |https|  
|サーバ名またはIP|google.co.jp|  
|HTTPリクエスト  |GET|
### 6. シナリオ実行
実行タブの「開始」を選択（または緑の再生ボタン（三角マーク）を押下）  
**※GUIからの実行はシナリオの確認でのみ使用すること※**  
コマンドラインからの実行方法は次項参照
### 7.  実行結果の確認
「結果をツリーで表示」で結果を確認
## コマンドラインからシナリオを実行する
### 1. Jmeterのbinフォルダで以下のコマンドを実行
```
jmeter -n -t scenario.jmx
```
|  オプション       |  説明  |
| ---------------- | ---- |
|  -n              |  Jmeterを非GUIモードで起動  |
|  -t [ファイル名]  |  テスト計画のJMXファイル名を指定  |
|  -l [ファイル名]  |  テスト結果を格納するJTLファイル名を指定  |
|  -e              |  負荷テスト後にレポートを出力する  |
|  -o [フォルダ名]  |  レポートを出力するフォルダを指定する。存在しないフォルダ名か空のフォルダを指定しなければならない。  |

テスト結果とレポートを出力する場合のコマンドは以下
 ```
jmeter -n -t scenario.jmx -l log.jtl -e -o report
```
## JsonファイルをPOSTする
### 1. HTTPヘッダマネージャの作成
  「HTTPリクエスト」を右クリック  
  追加 > 設定エレメント > HTTPヘッダマネージャ を選択
### 2. HTTPヘッダマネージャの設定
  追加ボタンを押下し、名前に「Content-Type」、値に「application/json」を入力
### 3. HTTPリクエストの設定
  HTTPリクエストをPOSTに設定、BodyDataにPOSTするjsonデータを入力  
（複数のHTTPリクエストに共通のヘッダを設定したい場合は、　スレッドグループに対してHTTPヘッダマネージャを作成することで、　スレッドグループ配下のHTTPリクエストすべてのヘッダ情報を設定できる）
## CSVファイルの内容をBodyに設定する
### 1. 「CSV Data Set Config」の作成
  「HTTPリクエスト」を右クリック  
  追加 > 設定エレメント > CSV Data Set Config を選択
### 2. 「CSV Data Set Config」の設定
  Filenameに読み取るCSVファイルのパスを設定  
  CSVファイルにヘッダがない場合は「Variable Names」に変数名を設定
### 3. HTTPリクエストの設定
  BodyDataでCSVから取得値を設定する箇所に変数名を設定  
  （例）  {"data":"${data}"}   ・・・「data」という変数をjsonの値に設定している  
  csvにヘッダがある場合は変数名＝ヘッダ、ヘッダがない場合は変数名＝CSV Data Set ConfigのVariable Namesの値
## HTTPSのWebサイトにリクエストを送る
以下のWebサイトを参考にSSL証明書をインストール  
[JMeterでHTTPSサイトをシナリオを記録する | ばったんの技術系ブログ (blackbird-blog.com)](https://blackbird-blog.com/jmeter-https-scenario)
## Basic認証のあるWebサイトにリクエストを送る
### 1. HTTP認証マネージャの作成
「スレッドグループ」を右クリック  
追加 > 設定エレメント > HTTP認証マネージャ を選択
### 2. HTTP認証マネージャの設定
追加ボタンを押下し、基底URL、ユーザ名、パスワードを入力
## セッション情報を保持する
### 1. HTTPクッキーマネージャを作成
「スレッドグループ」を右クリック  
追加 > 設定エレメント > HTTPクッキーマネージャ を選択  
※HTTPクッキーマネージャの設定は不要  
　作成しただけでセッション情報が保持されるようになる  
## リクエストパラメータで変数を使用する
### 1. ユーザ定義変数を作成
「スレッドグループ」を右クリック  
追加 > 設定エレメント > ユーザ定義変数 を選択
### 2. ユーザ定義変数の設定
追加ボタンを押下し、名前と値を入力
### 3. HTTPリクエストの設定
Parametersの値に変数を設定する  
（例）  ${USER}   ・・・「User」という変数をパラメータに設定している
## 前画面から取得したパラメータをリクエストパラメータに設定する
ログイン処理ではID・パスワードだけでなく、前画面からトークンを送信している場合がある。  
その場合は前画面から取得したトークンを次画面のリクエストパラメータに設定する必要がある。  
以下はその方法。  
### 1. 正規表現抽出を作成
トークン取得元の画面を取得するHTTPリクエスト※を右クリック  
追加 > 後処理 > 正規表現抽出 を選択  
※ログイン処理でトークンを送信する場合は、ログイン画面表示のHTTPリクエストが該当
### 2. 正規表現抽出の設定
|  設定項目   |  設定例  |  備考  |
| ---------- | ---- | ---- |
|参照名      |TOKEN| リクエストパラメータで設定する変数名 |
|正規表現    |\<input name="__RequestVerificationToken" type="hidden" value="(.*)" />|  |
|テンプレート |\$1$| 正規表現が複数ある場合に先頭から何番目の値を取得するかを指定する |

正規表現で取得するトークン（上記の例だと__RequestVerificationToken）は、トークン取得元の画面を取得したときのHTMLから探す。  
### 3. HTTPリクエストの設定
前画面から受け取ったパラメータを送信するHTTPリクエストのパラメータにトークンの名前（上記の例だと__RequestVerificationToken）と値（正規表現抽出の参照名）を設定  
参照名はユーザ定義変数と同じ表記で設定する（上記の例だと ${TOKEN ）
## ブラウザを操作してシナリオを作成する
### 1. HTTPプロキシサーバの作成
「テスト計画」を右クリック  
追加 > Non-Testエレメント > HTTPプロキシサーバ を選択
### 2. シンプルコントローラの作成
「スレッドグループ」を右クリック  
追加 > ロジックコントローラ > シンプルコントローラ を選択
### 3. HTTPプロキシサーバの設定
対象となるコントローラ で「テスト計画 > スレッドグループ > シンプルコントローラ」を選択
### 4. Windowsのプロキシサーバの設定
(1) Windowsの設定を開き、ネットワークとインターネットに移動  
(2) プロキシタブで「プロキシサーバを使う」をオン、アドレスは「http://localhost」、ポートは「8888※」を設定し、保存ボタンを押す  
※JMeterのHTTPプロキシサーバのポートの設定値
### 5. シナリオの作成
HTTPプロキシサーバで開始ボタンを押した後にブラウザを操作すると、シンプルコントローラにHTTPリクエストが記録される  
シナリオの記録が終わったらHTTPプロキシサーバの停止ボタンを押し、Windowsのプロキシサーバの設定をオフにする
## JMeterの参考記事
[【簡単】Webシステムの負荷テストツール（JMeter）の使い方 | ばったんの技術系ブログ (blackbird-blog.com)](https://blackbird-blog.com/jmeter-01)
# AWS分散負荷テストソリューションの使い方
JMeterはPC上で動作するため、1台のPCでWebサイトやWebシステムに1秒間で何千・何万のリクエストを送信することはできない。  
AWS分散負荷テストソリューションは、クラウド上にコンテナを複数構築して、それぞれのコンテナで並列にリクエストを送信することでWebサイト・Webシステムに高い負荷をかけられる。
## 準備
### 1. CloudFormationのテンプレートをダウンロード
以下のWebサイトで「CloudFormationテンプレート」のリンクをクリックしてCloudFormationのテンプレートをダウンロードする  
[AWS での分散負荷テスト | 実装 | AWS ソリューション (amazon.com)](https://aws.amazon.com/jp/solutions/implementations/distributed-load-testing-on-aws/)  

![aws.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2528939/5881f2d6-5279-e41d-bf3e-98733c633711.png)

### 2. CloudFormationでスタックを作成
(1) AWSにログインし、マネジメントコンソールからCloudFormationに移動  
(2) CloudFormationのトップ画面でスタックの作成ボタンをクリック  
(3) スタックの作成画面で、前提条件は「テンプレートの準備完了」、テンプレートの指定は「テンプレートファイルのアップロード」を選択し、アップロードするCloudFormationテンプレートを指定し、次へボタンをクリック  
(4) スタックの名前とConsole Administrator Name、Console Administrator Emailを入力し、次へボタンをクリック  
(他の項目は未入力または初期値の状態でOK)  
(5) スタックオプションの設定、詳細オプションは特に設定せず、次へボタンをクリック  
(6) 設定内容を確認し、「AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。」にチェックを入れて、スタックの作成ボタンをクリック
## ダッシュボードにログイン
(1) CloudFormationでスタックの作成が完了したらスタック作成時に設定したメールアドレスにメールが届くので、そこから負荷テストのWebサイト（ダッシュボード）にログインする  
（スタック作成の完了には10～15分ほどかかる）  
(2) 初回ログイン時にパスワードの変更が求められるので、新しいパスワードを設定する
## シナリオ作成と実行
ここではJMeterのシナリオを使う方法を紹介。

(1) ダッシュボードから「CREATE TEST」をクリック  
(2) General Settingsでシナリオの実行条件を設定する  
設定内容は以下

|  設定項目     |  設定内容              |  備考  |
| ------------- | --------------------- | ------ |
|  Name         |  シナリオの名前        |    |
|  Description  |  シナリオの説明        |    |
|  Task Count   |  起動するコンテナの数  |  デフォルトでは最大50※  |
|  Concurrency  |  コンテナごとの同時接続数  |  推奨上限値は200  |
|  Ramp Up      |  同時接続数に達するまでの時間  |    |
|  Hold For   |  同時接続数を維持する時間  |    |  

※ 上限緩和申請を行えば最大1000  
  
(3) ScenarioのTest Typeで「JMeter」を選択し、JMeterのシナリオファイル（Zipファイルにしておく※）を指定してRun Nowボタンをクリック  
※csvファイルなど、JMeterのシナリオファイルが参照するファイルもzipファイルに含める。  
　Jmeterで指定するファイルの参照先は相対パスにしておく。
## AWS分散負荷テストソリューションの参考記事
[AWSの負荷テストソリューションを試してみた | DevelopersIO (classmethod.jp)](https://dev.classmethod.jp/articles/distributed-load-testing-on-aws/)

# おわりに
JMeter、AWS分散負荷テストソリューションのそれぞれの情報はネットで調べれば情報がたくさん出てきますが、両方を合わせた記事は見つからなかったので投稿しました。