JMeterでグラフィカルに変幻自在なアクセス負荷を設定する(前編)

# はじめに

JMeterは一般的にWebシステムに一定のアクセス負荷をかける試験ツールです。
通常機能ではアクセス負荷量の上げ下げが困難ですが、外部ライブラリ(Throughput Shaping Timer)を組み込むことでグラフィカルかつ簡単に実現できたので紹介します。

# Throughput Shaping Timer で実現できること

- 自由度の高いアクセス負荷の制御ができる
- １台のJmeterで複数のスレッドグループ毎にアクセス負荷を制御できる
![sample_image](https://jmeter-plugins.org/img/wiki/throughput_shaping_timer1.png)
↑アクセス負荷量の制御イメージ　公式ページより

実際に負荷試験をする際に活用できるケースとして、以下のような例が当てはまると思います。

- 試験中に負荷量を定常量から急上昇（急降下）させてシステムの安定性を確認したい
- アクセス量に波があるシステムの試験をしたい
- スレッドグループ（アクセス導線）毎にきめ細やかな試験を同時に実施したい

アクセス負荷をどの程度制御できるのかについては、実際の設定交えて説明させていただきます。

# Throughput Shaping Timer を使ってみる

## 環境情報

環境情報

- Mac(Catalina)
- Apache httpd server(2.4.x)
- Java8(Oracle java 8u202)
- JMeter(5.3)

## 環境構築

### Apache httpd server

今回は簡易的な試験なので、Dockerでさくっと構築します。
試験対象のシステムがある方は構築不要です。
またNginxでもローカル環境構築でも、何でも大丈夫です！

1. 公式イメージの取得
<pre>
$ docker pull httpd
</pre>

1. コンテナ起動
<pre>
$ docker run -dit --name my-apache-app -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
</pre>

1. コンテナID確認
<pre>
$ docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                                           NAMES
e2dc7c3714ee        httpd:2.4           "httpd-foreground"   21 minutes ago      Up 21 minutes       0.0.0.0:8080->80/tcp, 0.0.0.0:32768->8080/tcp   my-apache-app
</pre>

1. コンテナ接続
<pre>
$ docker exec -it e2dc7c3714ee /bin/bash
</pre>

1. テストページ作成
<pre>
$ echo "hello" > ./htdocs/index.html
</pre>
> ここでapacheのドキュメントルートがMacのホームディレクトリになっている衝撃の事実が発覚。。。


1. ブラウザで接続確認
`URL http://localhost:8080/index.html`<br>
![スクリーンショット 2020-10-12 17.06.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/87c2a3c0-cc7f-d19d-bf00-7903e93cf2f1.png)


### Java

JMeterの実行にはJava8以上が必要です。
Javaのインストール方法は割愛します。
[【初心者でもすぐわかる】JDKのインストール方法 Mac編](https://eng-entrance.com/java-install-jdk-mac)

<pre>
$ java -version
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)
</pre>

### JMeter

1. JMeterをダウンロードして任意のディレクトリに展開
[ダウンロードページ](https://jmeter.apache.org/download_jmeter.cgi)
![スクリーンショット 2020-10-12 22.30.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/20e27f7a-ee84-07ae-1391-f1ef5b5e73c5.png)


1. ThroughputShapingTimerをダウンロード
[ダウンロードページ](https://jmeter-plugins.org/?search=jpgc-tst)
※最新のバージョン2.5をダウンロード
![スクリーンショット 2020-10-12 22.32.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/dc68fa4f-3c86-c5c4-b4fc-081956cb8a2e.png)

1. ThroughputShapingTimerを配置
ダウンロードしたプラグイン（jpgc-tst-2.5.zip）を展開し、
中に含まれる以下３つのjarファイルをJmeterのlibディレクトリに配置する。
配置先：`<JMeterを展開したディレクトリ>/apache-jmeter-5.3/lib`
 - jmeter-plugins-cmn-jmeter-0.5.jar
 - ext/jmeter-plugins-manager-1.1.jar
 - ext/jmeter-plugins-tst-2.5.jar
![スクリーンショット 2020-10-12 22.44.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/0d6152d7-825d-7ad4-af1b-84ac2e46213a.png)
※３つとも階層構造を維持したまま配置すること

1. JMeterを起動
<pre>
$ cd <JMeterを展開したディレクトリ>/apache-jmeter-5.3/bin
$ sh ./jmeter.sh
</pre>
※Windowsの場合は同一階層の`jmeter.bat`をダブルクリックします
![スクリーンショット 2020-10-12 22.53.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/5d0c2862-3a7c-7d0c-6e0d-a6a4fa67a32a.png)
準備はここまでです、お待ちかねの実践編です！

## 負荷量を設定してみる（初級編）

### 状況設定
A君「このシステムは普段100tpsのアクセスがあるので、JMeterから１０分間負荷をかけて試験します！」
上司「普段はその程度だけど、もしTwitterでバズってアクセス量が瞬間的に５倍になったらどうなる？」
A君「うーん、、、わからないです、、、（ならんやろ、、、）」

A君とJMeterの壮絶な性能試験がここから始まる！
※フィクションです

### Jmeterを設定してみる

JMeterの基本的操作については割愛しています。

1. スレッドグループを追加する
実行時間はThroughputShapingTimerで制御するので、ループ回数は無限に設定します。
![スクリーンショット 2020-10-12 23.40.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/093e7c98-f996-5ca2-ed21-1652dc67716d.png)


1. HTTPリクエストサンプラーを追加する
 - プロトコル：`http`
 - サーバ名またはIP：`localhost`
 - ポート番号：`8080`
 - パス：`/index.html`
![スクリーンショット 2020-10-12 23.34.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/bae74850-d616-a463-555c-2ff1d790ae9a.png)

1. 統計レポートを追加する
 - ファイル名：`任意の保存先を指定`
![スクリーンショット 2020-10-12 23.19.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/850f90d5-4d29-2781-6692-01fbdbfed6f2.png)

1. Throughput Shaping Timerを追加する
![スクリーンショット 2020-10-12 23.20.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/11f2fa74-cf87-adc3-9a17-6d78a499430b.png)
![スクリーンショット 2020-10-12 23.22.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/67fffb16-3eea-9078-75ee-98ffa2ba38ef.png)

1. 負荷量を設定する
操作方法：
 - `Add Row`をクリックして設定行を追加する　※行が時系列になります
 - `Start RPS`に開始時の負荷量を設定する　※RPS=RequestPerSecond
 - `End RPS`に終了時の負荷量を設定する
 - `Duration, sec`に継続時間を設定する
![スクリーンショット 2020-10-12 23.25.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/44223926-db4b-487b-1816-e7d898431bf8.png)
設定すると画面下部にリアルタイムでグラフが描写されるので、実際に試してみましょう！

1. スレッドグループを実行する
![スクリーンショット 2020-10-12 23.36.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/7c69cb6e-628a-c7fc-01ab-c621d414faf1.png)

### 実行結果を確認する

#### 統計レポート

アクセス回数はだいたい予定通りですね。
![スクリーンショット 2020-10-12 23.43.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784816/23973485-3692-1fce-cdfe-dd89fad4b293.png)

#### Apacheログ

1. コンテナID確認
<pre>
$ docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                                           NAMES
e2dc7c3714ee        httpd:2.4           "httpd-foreground"   7 hours ago         Up 36 minutes       0.0.0.0:8080->80/tcp, 0.0.0.0:32771->8080/tcp   my-apache-app
</pre>

1. Apacheログ解析
<pre>
$ docker logs e2dc7c3714ee | grep test01 | awk '{print $4}' | sed 's/\[12\/Oct\///g' | uniq -c
   1 2020:14:38:12
   1 2020:14:39:09
   3 2020:14:39:10
   4 2020:14:39:11
   6 2020:14:39:12
   8 2020:14:39:13
  11 2020:14:39:14
  10 2020:14:39:15
   9 2020:14:39:16
  11 2020:14:39:17
  10 2020:14:39:18
   9 2020:14:39:19
  11 2020:14:39:20
  10 2020:14:39:21
   9 2020:14:39:22
  11 2020:14:39:23
  10 2020:14:39:24
  10 2020:14:39:25
  10 2020:14:39:26
   9 2020:14:39:27
  11 2020:14:39:28
  10 2020:14:39:29
  10 2020:14:39:30
  10 2020:14:39:31
  10 2020:14:39:32
   9 2020:14:39:33
  11 2020:14:39:34
  17 2020:14:39:35
  26 2020:14:39:36
  34 2020:14:39:37
  42 2020:14:39:38
  51 2020:14:39:39
  41 2020:14:39:40
  35 2020:14:39:41
  26 2020:14:39:42
  17 2020:14:39:43
  10 2020:14:39:44
  10 2020:14:39:45
  10 2020:14:39:46
  10 2020:14:39:47
  10 2020:14:39:48
  10 2020:14:39:49
   9 2020:14:39:50
  11 2020:14:39:51
  10 2020:14:39:52
  10 2020:14:39:53
  10 2020:14:39:54
   9 2020:14:39:55
  10 2020:14:39:56
  11 2020:14:39:57
  10 2020:14:39:58
  10 2020:14:39:59
  10 2020:14:40:00
   9 2020:14:40:01
  11 2020:14:40:02
  10 2020:14:40:03
  10 2020:14:40:04
</pre>
第一項目は秒間のアクセス量、第二項目は時間です。
だいたい10RPSをキープし、負荷量が一時的に50RPSまで上昇したことがわかりますね。

### 後日談

JMeterでアクセス負荷量を変幻自在に操ることに成功したA君
A君「Twitterでバズった時を想定したアクセス増加、JMeterで試験できそうです！」
上司「結果見せてもらったけど、単一ページへの試験しかできてないよね。ユーザがトップページから人気ページへ辿っていくケースを想定して試験欲しいんだけど。。。」
浮かれていたA君、しかし本当の戦いはこれからだった
**次回：『もう何も怖くない』**

# さいごに

簡単な説明になりましたが、ThroughputShapingTimeの可能性を感じてもらえたかと思います。
しかしWebアプリケーションの試験ではサンプルページのみにアクセスするということは、まずありえません。
今回は簡単な使い方の紹介までとし、次回の記事で実践的な使い方を解説していきたいと思います。

続編はこちら
↓
[JMeterでグラフィカルに変幻自在なアクセス負荷を設定する(後編)](https://qiita.com/Kenta-Sado/items/0f509320c0543ed025c3)

# 参考
[ThrouputShapingTimer](https://jmeter-plugins.org/wiki/ThroughputShapingTimer/)
[DockerHub Apache httpd](https://hub.docker.com/_/httpd)