AWS EC2でJMeterを実行しよう

# 本稿の目的
- JMeterのデメリットを改善したソフトウェアを開発するための第一歩として使い方、pros/consを整理します。
- JMeterの負荷テストはローカルマシンからではまず不十分なので、EC2で実施するための簡単な手順を記録します。
- AWS EC2で実施しましたが、他のクラウドのVMでも使えると思います。

なお、「JMeterって何？」という方は参考記事一覧から読むことをお勧めします。
# JMeterとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636063/3cdeb36a-6f41-d6c0-5883-e1a5c4a45ddb.png)
Apache謹製のLoad testing tool。HTTPなどのプロトコルで、Web上のサービスに対して負荷テストを実行するのが目的。負荷テストの詳細は.jmxファイル形式で管理され、テストのポータビリティが担保されている（嬉しい）。

メリット
- GUIが優れていて直感的にload testsを作れる
- GUIからもテストが実行可能で、テスト結果がグラフィカルに見られる

デメリット
- マルチノードの分散テストは管理が難しい
- GUIからではきちんと負荷テストを行えない
- その他あれば書いていきましょう

（余談）
一点目は結構致命的です。例えば[こちら](https://ieeexplore.ieee.org/abstract/document/6413663?casa_token=lH3ITCyBpTsAAAAA:77iHpv3RHdKMBqs3uK1h03uGRfoXuMElS7x7IUoY8jMAnHvhfMxAOAjmO0s6ntxELwm83S8)で指摘されているような超高負荷かつ地理的にも分散的なアクセスは、1つのノードからではほぼ再現不可能です。例えば、最高水準のEC2インスタンス[r7iz.32xlarge](https://instances.vantage.sh/aws/ec2/r7iz.32xlarge)でも、128vCPUsなので、128スレッドしかサポートできません。一方で、[c5d.xlarge](https://instances.vantage.sh/aws/ec2/c5d.xlarge)でも100台並列できれば400vCPUsです。

# EC2でJMeterを実行しよう
実際にEC2でJMeterを実行する手順です。
## インスタンス情報
**c5a.24xlarge(96vCPUs, 192GiB) Spot instance**
**Ubuntu 22.04 LTS**
単に試したいだけならここまでのインスタンスは必要ありません。しかし、JMeterはマルチスレッド実行なので、しっかり負荷をかけるには相応のvCPUsがあったほうが恩恵に預かりやすいです。
現状（2024年2月）、このインスタンスだとオンデマンドで 4ドル/h、スポットインスタンスで1~2ドル/h程度です。よーしテストするためにインスタンス立ち上げちゃうぞ〜！っていう前に、テスト内容と手順はしっかり定めておきたいなと思うプライシング帯ですね。第７世代のほうが安いんですが、人気ゆえかスポットリクエストだと私のリージョン（us-east-2）ではあまり手に入りませんでした。

※私だけかもしれませんが、AWSのService Quotaで、# max vCPUsが初期だと32になってるかもしれません。以下2個のどちらかで解決できます。
1. Spot instanceの# max vCPUsを96に上げて、spot instance requestをする。
2. オンデマンドインスタンスの# max vCPUsを96に上げて、オンデマンドインスタンスを起動する。

１はリクエストすればすぐできます。２はリクエストしても24時間程度時間がかかりそうです。
## 実行環境の整備
JMeterはjavaがインストールされていればどこでも実行できます。端的に言えば必要なのは3つだけです。
1. JDK
1. JMeterの実行ファイル等（後述しますがwgetできます）
1. テスト情報の記載されたjmxファイル

なお、
```bash
$ sudo apt install jmeter
```
これでもインストールできるという記事もありましたが、私はこれではうまくいきませんでした。（理由を知っている方がいれば教えてください）

上記１〜３を実行するコマンドが以下です。

まずはEC2インスタンスにsshで接続しましょう。
```bash
$ ssh -i (秘密鍵) ubuntu@YourServerIP
```
```bash
# aptのアップデート
$ sudo apt update
# JDKのインストール
$ sudo apt install openjdk-17-jre-headless
# JMeterプロジェクトの取得と解凍
$ wget https://dlcdn.apache.org//jmeter/binaries/apache-jmeter-5.6.3.tgz
$ tar vxzf apache-jmeter-5.6.3.tgz
```
これでリモートでの実行環境は整いました。なお、デフォルトではEC2ではGUIは使えないので、jmxファイルをGUIから作れる超便利機能は使えません。よって、jmxファイルはローカルで作ってscpやS3経由でEC2インスタンスに送り込みましょう。
ここでは、ローカルからscpで送信するスクリプトのみ記載します。行ったり来たりになってしまいますが、このコードはローカル実行です。
```bash
$ scp  -i (秘密鍵)  /path/to/your/jmxfile.jmx\
                   ubuntu@(YourServerIP):/home/ubuntu
```

## JMeterの実行
リモートホストからJMeterを実行しましょう。Ubuntuなのでhome(~/home/ubuntu)にいる想定です。この時、
```
home/
　└ ubuntu
　　 　├ apache-jmeter-5.6.3
      | 　　　　　　└ bin
      |               └ jmeter 　
      └ jmxfile.jmx
 ```
　というディレクトリ構成になっていることを想定しています。
 以下のコマンドでjmeterテストを実行します。
```bash
# ログファイルなし最も単純版
$ apache-jmeter-5.6.3/bin/jmeter -n -t jmxfile.jmx
# ログの出力先を指定
$ apache-jmeter-5.6.3/bin/jmeter -n -t jmxfile.jmx  -l log.jtl
```
実行結果は、jmxファイルに記載した通りに出力されます。EC2からローカルに戻したい時はまたscpやS3経由で戻すといいです。
```bash
scp -i (秘密鍵) ubuntu@YourServerIP:/home/ubuntu/(リザルトファイル名) /(ローカルホスト上のパス)
```
# 参考記事
https://qiita.com/aidy91614/items/d96ca0261665abc54f7d

https://iret.media/15127

https://gametech.vatchlog.com/2020/11/19/aws-ec2-jmeter/

https://qiita.com/Maimon/items/9fff772349e2421a3f20

https://qiita.com/shotets/items/d553d7be0d407a9a9a53