【ELB】AWS ELBの負荷テストをJMeterServer群でやる【負荷テスト】


__更新履歴__

* 2014/2/17 コメント頂いた内容を反映、誤字を修正


#なぜELBの負荷テストはJMeterクライアント（GUI）１台からではだめか。

当初、ELB配下に、AZ-Aに2台、AZ-Cに2台の合計4インスタンスがある構成で、自分の開発マシンでJMeter(GUI)を動かして負荷テストをしていたのですが、なぜか、AZ-Aの2台にしか負荷が入っていない。

ググっていたら、AWS Japanの公式スライドを発見
http://www.slideshare.net/AmazonWebServicesJapan/20130612-aws-meisterregenerateelbpublic

↑のp49に、 __「都度DNS解決を行うツールが望ましい」__ とあります。

なるほど確かに、JMeterはDNSキャッシュしてしまっているようです。↓
https://twitter.com/just_do_neet/status/331804161379270656


[「SpotInstanceとJMeterを使って400万req/minの負荷試験を行う」](http://dev.classmethod.jp/cloud/apache-jmeter-master-slave-100mil-req-min/)

↑を参考に、JMeterサーバーを複数個立ち上げて負荷試験することにします。

#構成

##クライアント

サーバのコントローラ（クライアントと呼びます）は、開発マシンなど手元のマシンで良いです。
複数コントローラはこの手元のクライアントのGUIより操作できます。

##サーバ

サーバはAWS上に構築します。実際にテスト対象に負荷をかける人たちです。
注意点として、これらのサーバからの通信をクライアントが受け付ける（クライアント側のInBound）ネットワーク設定が必要です。
（クライアント→サーバ　だけでなく、クライアント←サーバも必要ということ）
多分、VPCおよびVPN構築するのが手っ取り早いと思います。
VPNの構築は、VPCに対するハードウェアVPNと、VPC内にVPNサーバを立てるソフトウェアVPNの選択肢があると思いますが、好きな方でどうぞ。

このサーバのInBoundは、22(ssh)、1099、40000を開けてください。

##テスト対象

ELB配下に複数台マシンがぶら下がっている状態で準備してください。

#サーバの構築

```shell
$ mkdir ~/src
$ cd ~/src
$ wget http://ftp.riken.jp/net/apache//jmeter/binaries/apache-jmeter-2.11.tgz
$ tar zxvf apache-jmeter-2.11.tgz
$ cd apache-jmeter-2.11
```

```bin/jmeter.properies
server.rmi.localport=40000
```

最後の方のJava起動スクリプトを、以下に修正

```bin/jmeter-serverを編集

${DIRNAME}/jmeter ${RMI_HOST_DEF} -Dsun.net.inetaddr.ttl=0 -Dserver_port=${SERVER_PORT:-1099} -s -j jmeter-server.log "$@"

```

また、クライアント名の解決がなぜかIPアドレスだとうまくいかなかったので、hostsにクライアントのIPアドレスと名前を付けています。



```/etc/hosts
[クライアントのIPアドレス] jmeter-client
```


#クライアントの構築

クライアントはMacで実行しましたが、
Windows等でも変わらないと思います。Java必須です。

apache-jmeter-2.11をダウンロードして解凍してください。

```bin/jmeter
#
#上は省略
#

#この行を追加。↓サーバ側に設定した名前と一致させる
JVM_ARGS="-Djava.rmi.server.hostname=jmeter-client"

ARGS="$SERVER $DUMP $HEAP $NEW $SURVIVOR $TENURING $EVACUATION $PERM"

java $ARGS $JVM_ARGS -jar "`dirname "$0"`/ApacheJMeter.jar" "$@"
```

以下、サーバの数だけ、「,」で区切ってアクセスIPとポートを指定してください。

```jmeter.properties
#163行目付近
remote_hosts=[サーバ1のIPアドレス]:1099,[サーバ2のIPアドレス]:1099,...
```



#テスト実行

##クライアント準備

クライアントで、JMeterを起動します

```shell
$ sh /path/to/jmeter_dir/bin/jmeter
```

↑によってGUIが立ち上がります。

「実行」メニューの、「開始（リモート）」にサーバのIPアドレスが羅列されているのを確認してください。

テスト計画を普通に作って下さい。
注意点として、スレッドグループで定義したリクエストは、各サーバ毎に実行されます。

たとえば、サーバを4台で実行するとします。
スレッドグループでスレッド数を10、ループを20とすると、合計のリクエスト数は、以下の計算式になります。

4(サーバ) × 10(スレッド数) × 20(ループ) = 800(リクエスト)

##サーバ準備

```shell
$ cd ~/src/apache-jmeter-2.11/bin
$ sh jmeter-server
```

##テスト実行
クライアント側の、「実行」メニュー→「全て開始(リモート)」にて実行します。









#余談編：あれ？負荷がかかってない？

いざ負荷をかけてみると、なにやら途中で負荷が抜けている模様

↓ __CPU使用率__

![スクリーンショット_14_02_17_14_28-17.jpg](https://qiita-image-store.s3.amazonaws.com/0/34165/21bee02d-c7a4-2ceb-1a4d-30fdb11cbea8.jpeg "スクリーンショット_14_02_17_14_28-17.jpg")


↓ __リクエスト数__

![スクリーンショット_14_02_17_14_35-4.jpg](https://qiita-image-store.s3.amazonaws.com/0/34165/753d9b8e-380d-0dbc-be4e-86901cbd2e5f.jpeg "スクリーンショット_14_02_17_14_35-4.jpg")

@understeer よりコメント頂きました。ありがとうございます。

_ELBはエンドポイントとマッピングするIPアドレスが負荷に応じて変わりますから、JMeter サーバを起動するときにも注意が必要です。
http://wiki.apache.org/jmeter/JMeterAndAmazon
にも書いていますが、JVMの起動パラメータ -Dsun.net.inetaddr.ttl　を適切に設定してください。_


ELB自体が負荷に応じてスケールIn・Outするため、このようなことがおきるんですね。

リンクの通り、JMeterServerの起動時のオプションで、
-Dsun.net.inetaddr.ttl=0を設定します。

```shell
$ cd ~/src/apache-jmeter-2.11
```

```bin/jmeter-serverを編集
#最後の方のJava起動スクリプトを、以下に修正

${DIRNAME}/jmeter ${RMI_HOST_DEF} -Dsun.net.inetaddr.ttl=0 -Dserver_port=${SERVER_PORT:-1099} -s -j jmeter-server.log "$@"

```

##結果どうなったか

![EC2_Management_Console.jpg](https://qiita-image-store.s3.amazonaws.com/0/34165/afc66212-f3b5-753c-1de0-38067eacd21f.jpeg "EC2_Management_Console.jpg")

__負荷が抜けてない！__

お疲れ様でした。