Jmeterで簡単負荷試験

## ダウンロード
https://jmeter.apache.org/download_jmeter.cgi に行きBinariesから解凍可能な形式のバイナリをダウンロードします。

## 起動
WindowsとMac, Linuxで少々違うようです。

### Windows
ダウンロードした `apache-jmeter-5.2.1`（2020/2/28時点） ディレクトリを開きます。
`bin`ディレクトリ内の `jmeter.bat` をダブルクリックし起動してください。
GUIが開いたら起動完了です。

### Mac, Linux
ターミナルを起動します。
ダウンロードした `apache-jmeter-5.2.1`（2020/2/28時点）に移動します。
`bin/jmeter.sh`を実行します。
GUIが開いたら起動完了です。

## 負荷試験
さて本題です。
あるAPIに対しての性能試験をする事を想定してJmeterの設定をしていきます。
APIの定義をいくつかしておきましょう。

### API定義
#### POST /api/v1/login
##### header
```json
{
  "Content-Type": "Application/json",
}
```

##### request
```json
{
  "username": "jmeter",
  "password": "apache"
}
```

##### response
```json
{
  "token": "bhknFCZWaCDME1KhGz5wdbBx"
}
```

#### GET /api/v1/users
##### header
```json
{
  "Authorization": "bhknFCZWaCDME1KhGz5wdbBx",
}
```

##### request
```json
{}
```

##### response
```json
{
  "users": [
    {
      "username": "Aさん"
    },
    {
      "username": "Bさん"
    }
  ]
}
```

### シナリオ作成
`/api/v1/login`でログインし、`/api/v1/users`にアクセスすることにします。
`/api/v1/login`でアクセストークンを取得し、そのアクセストークンを使って`/api/v1/users`にアクセスします。

1. スレッドグループを作成します。
2. ログイン処理のために「一度だけ実行されるコントローラ」を追加します。
3. `/api/v1/login`のHTTPリクエストを追加します。
4. HTTPリクエストに後処理を追加し、アクセストークンを抽出します。
5. `/api/v1/users`のHTTPリクエストを追加します。

画像を添付しつつ説明します。

#### 1. スレッドグループを作成
「テスト計画」を右クリックし「追加」→「Threads(Users)」→「スレッドグループ」をクリックします。
<img width="1537" alt="スレッドグループ作成" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79633/f4c8e92f-fa59-3733-3ade-1d1e87fff5d5.png">

#### 2. ログイン処理のために「一度だけ実行されるコントローラ」を追加
「スレッドグループ」を右クリックし「追加」→「ロジックコントローラ」→「一度だけ実行されるコントローラ」をクリックします。
<img width="1426" alt="1度だけ実行されるコントローラ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79633/bd48f19a-ee5d-6c99-6e5f-ea979a45b9cb.png">

#### 3. `/api/v1/login`のHTTPリクエストを追加
「一度だけ実行されるコントローラ」を右クリックし「追加」→「サンプラー」→「HTTPリクエスト」をクリックします。
追加できたら、追加した「HTTPリクエスト」を選択し内容を入力します。

##### プロトコル
`http`か`https`を入力します。（サーバーにあったものを入力してください）
##### サーバ名またはIP
ホストネームを入力します。
##### ポート番号
サーバーがバインドしているポートを入力します。
##### メソッド
HTTPメソッドを選択します。
##### パス
APIのパスを入力します。
##### Parameters
リクエストで送るパラメータ。いわゆるクエリパラメータ。
今回は定義に合わせて、`username`と`password`を含めます。

<img width="1424" alt="ログインHTTPリクエスト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79633/ced5aca8-6787-e6c6-aa0c-f84976632808.png">

<img width="1426" alt="ログインHTTPリクエスト入力例" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79633/045d303d-9ae6-1fbe-41c0-1ef779cddbc6.png">

#### 4. HTTPリクエストに後処理を追加しアクセストークンを抽出
ログイン処理のレスポンスにアクセストークンが含まれていますが、このままでは次のアクセスにアクセストークンを含めることができません。
レスポンスを抽出して保存する必要があります。

3で追加した「HTTPリクエスト」を右クリックし「追加」→「後処理」→「正規表現抽出」をクリックします。
追加した「正規表現抽出」を選択し内容を入力します。
それぞれの入力内容については[こちら](http://sy5.sakura.ne.jp/jmeter/ref/postprocessors/regularexpressionextractor.html)を参照ください。

##### 参照名
抽出した値を呼び出すための名前。好きな名前でOKです。
今回はわかりやすくパラメータと同じ名前をつけています。

##### 正規表現
抽出するパラメータの正規表現を入力します。()で囲っている部分を抽出します。

##### テンプレート
正規表現にマッチした値グループの内どれを使用するかを指定します。`$n$`でグループを選択する。先頭は1。


<img width="1425" alt="正規表現抽出" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79633/3bc6adf1-d28d-2c64-1601-7baec6525222.png">
<img width="1425" alt="後処理入力例" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79633/0b08ecf4-4bdc-aab9-e2d6-9a1a87d45c94.png">


#### 5. `/api/v1/users`のHTTPリクエストを追加
「スレッドグループ」を右クリックし「追加」→「サンプラー」→「HTTPリクエスト」をクリックします。
追加した「HTTPリクエスト」を選択し内容を入力します。
接続先情報は3と一緒ですので割愛します。
`/apiv1/users`へアクセスするにはヘッダにアクセストークンを含める必要があるのでヘッダ情報を追加します。
「HTTPリクエスト」を右クリックし「追加」→「設定エレメント」→「HTTPヘッダマネージャ」をクリックします。
「HTTPヘッダマネージャ」を選択しパラメータを追加します。
今回は`{Authorization: Token ${token}}`を追加します。入力の仕方は画像を参照ください。

<img width="1426" alt="HTTPヘッダマネージャ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79633/6d20cfa0-ef5e-29fd-a88c-f7cb953d92fc.png">
<img width="1422" alt="HTTPヘッダマネージャ入力例" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79633/784180a1-c818-01a3-281b-06bf0b709950.png">

### 試験
#### 負荷レベル
「スレッドグループ」を選択すると以下の項目が表示されます。

- スレッド数
- Ramp-Up期間(秒)
- ループ回数

##### スレッド数
実行数。ユーザー数のように捉えたら良いです。
同時接続件数を指定する場合はここを調整します。

##### Ramp-Up期間(秒)
指定した秒数をかけてスレッドを立ち上げます。
例えば、スレッド数が5、Ramp-Up期間が5の時
1秒あたり1スレッドが実行されることになります。

##### ループ回数
名前の通りです。
このスレッドグループのシナリオを繰り返す回数です。

#### 実行
`▶︎`ボタンを押してRunしましょう。

### おまけ
「スレッドグループ」を右クリックし「追加」→「リスナー」→「統計レポート」を追加すると、シナリオのスループットやエラー件数のレポートを確認できるようになります。

## 参考
Jmeter簡易リファレンス http://sy5.sakura.ne.jp/jmeter/ref/postprocessors/regularexpressionextractor.html