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


更新履歴

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

なぜELBの負荷テストはJMeterクライアント(GUI)1台からではだめか。

当初、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の負荷試験を行う」

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

構成

クライアント

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

サーバ

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

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

テスト対象

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

サーバの構築

$ 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起動スクリプトを、以下に修正


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

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

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

クライアントの構築

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

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

#
#上は省略
#

#この行を追加。↓サーバ側に設定した名前と一致させる
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を起動します

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

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

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

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

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

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

サーバ準備

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

テスト実行

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

余談編:あれ?負荷がかかってない?

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

CPU使用率

リクエスト数

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

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

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

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

$ cd ~/src/apache-jmeter-2.11
#最後の方のJava起動スクリプトを、以下に修正

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

結果どうなったか

負荷が抜けてない!

お疲れ様でした。