JMeterを使って負荷試験をやったときのメモ

# 概要
- アプリケーションの負荷試験のためにJMeterを使用した
- いろいろ調べたり、触ったりして知ったことをメモしておく
- 環境はMacを想定しています！

# インストール
brewコマンドを使えば一発！

```
brew install jmeter
```

# 起動
コマンドで`jmeter`を実行するとGUIが起動する

```
jmeter
```
<img width="1148" alt="スクリーンショット 2019-05-18 15.48.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/0bbc1cd6-710c-5315-5b99-f764b0fe2f8c.png">

# 日本語化
Options > Choose Language > Japanese

# 負荷テストまでの手順

## テスト対象の用意
今回はローカルに
http://localhost:8080/hello
でアクセスを受け付けるアプリケーションを準備しました。
どんなものでも構わないですが、今回はSpringBootを使って用意しました

```java
@Controller
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @GetMapping
    @ResponseBody
    public String hello() {
        return "Hello World!";
    }
}
```

## スレッドグループの追加
それでは実際にjmeterを使用してみます
先ほど起動したGUIに戻ります

まずは
Test Plan（右クリック）　＞　追加　＞　Threads　＞　スレッドグループ
でスレッドグループを追加します

<img width="1143" alt="スクリーンショット 2019-05-18 16.25.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/e2bab16a-a5c5-1901-38e0-3f4b691a57c4.png">


以下それぞれの入力項目についてです

### 名前／コメント
ここはスレッドの説明用で、特にjmeterの動きを制御するものではないので、好きな名前を！

### スレッド数
実行時にどれくらいのスレッドを立ち上げるかを設定します。
webアプリケーションであればユーザ数、
apiであれば叩き元のアプリケーション数や並列数になると思います

### Ramp-Up期間
ここで「10」と設定すると１０秒後にすべてのスレッドが立ち上がるようになります。
例えば
- スレッド数：１０
- Ramp-Up期間：10
と設定したとすると１秒ごとに１スレッドが起動するイメージです
※起動タイミングを乱数で制御している旨の記事を見かけたので実際は綺麗に１秒ごとにスレッドが起動する動作にはならなそうです（検証してません）

### ループ回数
１スレッドが何回サンプルを実行するかを設定します。
設定した回数を実行し終わるとスレッドが終了します。
無限ループにチェックを入れると後述のスケジューラの持続時間中、サンプルを実行し続けます。

### 持続時間
スケジューラ設定の設定項目の一つ。
ループ回数を無限とした時に、ここで設定した秒数でスレッドが終了します

## サンプラーの追加
サンプラを追加します。
今回はwebアプリケーションの性能を測定したい想定なので
スレッドグループ　＞　追加　＞　サンプラー　＞　HTTP　リクエスト
を選択します。

<img width="1144" alt="スクリーンショット 2019-05-18 16.35.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/c1778fc2-d81a-8b01-1574-34c2ed716d6c.png">

Basicタブの入力項目はかなり直感的にいける気がします。
Advancedタブは今度触ってみます。。。

リクエストパラメータやPOSTメソッドでボディが必要な場合には、画面下部で設定できます。
画像の状態だと、`param=value`がリクエストパラメータに設定されます。

## リスナーの追加
試験結果をGUIで確認するために
HTTP リクエスト　＞　追加　＞　リスナー
からリスナーを追加しておく

### 統計レポート
以下のような統計レポートを表示してくれる
- 最大レスポンスタイム
- 最小レスポンスタイム
- 99%ite
- エラーの割合
- rps（Throughput）

### 結果をツリーで表示
HTTPリクエストをしたときの情報を表示しれくれる。
小さいスレッド数でまず動作確認したいときにあると便利。

## いざ実行！
フロッピーマークで設定を保存してから、緑色の右向きの三角を押せばスタート！
統計レポートをみると、実行した結果をみることができる。

<img width="1384" alt="スクリーンショット 2019-05-18 16.47.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/8b6b29a4-bfd3-4748-b2ca-594716882094.png">

１台で400rpsを遅延なく食えてる！優秀！笑

ここではGUIを使用したが負荷テストをしたい場合は、GUIは非推奨なよう。
起動時のコマンドラインをみてみると、jmeterコマンドを使用してテストしてねとのこと。

```
$ jmeter
================================================================================
Don't use GUI mode for load testing !, only for Test creation and Test debugging.
For load testing, use CLI Mode (was NON GUI):
   jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]
& increase Java Heap to meet your test requirements:
   Modify current env variable HEAP="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m" in the jmeter batch file
Check : https://jmeter.apache.org/usermanual/best-practices.html
================================================================================
```

なので負荷テストをしたいときは
- GUIで小さい負荷で設定＆テスト
- GUIで大きい負荷を設定して保存
- 保存されたjmxファイルを元にコマンドで負荷テストを実行
の流れがよさそう

# その他Tips

## ヘッダーを乗せたい
HTTP リクエスト　＞　追加　＞　定数エレメント
から「HTTPヘッダマネージャ」を追加
<img width="940" alt="スクリーンショット 2019-05-18 17.05.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/7d885bbc-7cea-c19d-b702-c710f52fec42.png">

## Cookieを乗せたい
HTTP リクエスト　＞　追加　＞　定数エレメント
から「HTTPクッキーマネージャ」を追加
<img width="1330" alt="スクリーンショット 2019-05-18 17.07.
37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/62eacfb3-75e4-63ec-e3a6-dd35f516ffe2.png">

## 特定のrpsで負荷試験をしたい
HTTP リクエスト　＞　追加　＞　タイマ
から「定数スループットタイマ」を選択する
<img width="1334" alt="スクリーンショット 2019-05-18 17.09.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/c16a0331-e22a-d140-42a4-9204f7f0c958.png">

ターゲットスループットの単位が「サンプル数/分」なので
100rpsの負荷をかけたければ6000を設定する（100rps×60秒）。

また「Caluculate Throughput base on」は「all active threads in current thread group」を選択する
※複数のスレッドグループで同時に負荷をかけるような場合には「all active threads」も選択肢に入るかも

また、スレッドグループの設定値も調整が必要
- スレッド数：「目標rps / 最大レシポンスタイム（秒）」
- Ramp-Up期間：任意
- ループ回数：無限ループにチェック
- スケジューラ設定：持続時間を任意に設定