AWSで動作するJMeterのMaster/Slave環境を構築した際の手順メモです。
OSはCentOS 7です。
※2019/5/19: JMeter(5.1.1)に合わせて内容を更新しました。
環境構築時の各バージョン
- OS: CentOS Linux release 7.6.1810 (Core)
- JMeter: apache-jmeter-5.1.1
- JMeterプラグイン:
- JMeter Plugins Manager 1.3
- jpgc - Standard Set 2.0
- JDK: java-1.8.0_212-openjdk
- 作業PC: Mac OS X 10.14.3
前提
- JMeterのテスト計画は、作業PC上に作成済みのjmxファイルがある前提とします。
- AWS上のJMeter(Master/Slave)はコマンドラインで実行するものとします。(今回はGUI環境の構築はしませんでした)
手順
AWSでJMeter用のセキュリティグループを作成
EC2ダッシュボードのセキュリティグループメニューを開き、「セキュリティの作成」を押す。
セキュリティグループ名と説明の欄に適当な名前(例:jmeter)を入力し、「作成」を押す。
作成したセキュリティグループを選択し、インバウンドルールに以下を追加する。
タイプ | プロトコル | ポート範囲 | 送信元 |
---|---|---|---|
SSH | TCP | 22 | マイIP |
カスタムTCPルール | TCP | 1099 | カスタムIP - JMeter用のセキュリティグループID |
カスタムTCPルール | TCP | 30000 - 65535 | カスタムIP - JMeter用のセキュリティグループID |
AWSでJMeter用のEC2インスタンスを作成
ステップ 1: Amazon マシンイメージ(AMI)
EC2ダッシュボードでインスタンスメニューを開き、「インスタンスの作成」を押す。
AWS Marketplaceを選択し、「CentOS 7」で検索する。
「CentOS 7 (x86_64) with Updates HVM」を選択する。
ステップ 2: インスタンスタイプの選択
任意のインスタンスタイプを選択し、「次の手順: インスタンスの詳細の設定」を押す。
※JMeterで数万リクエスト/秒を超えるような高負荷をかける場合には、それなりの性能や帯域が必要になるので、インスタンスタイプは「m4.xlarge」以上が適当と思われる。
ステップ 3: インスタンスの詳細の設定
設定画面で以下を選択し、「次の手順: ストレージの追加」を押す。
- インスタンス数: 1
- 購入のオプション: 選択なし
- ネットワーク: デフォルト
- サブネット: 優先順位なし
- 自動割り当てパブリック IP: サブネット設定を使用(有効)
- 配置グループ以下の設定は任意
ステップ 4: ストレージの追加
ボリュームタイプに「汎用(SSD)」を選択し、「次の手順: インスタンスのタグ付け」を押す。
ステップ 5: インスタンスのタグ付け
「タグの追加」を押し、追加された行に適当なタグ名(例:キーの欄に「Name」、値の欄に「jmeter」)を入れ、「次の手順: セキュリティグループの設定」を押す。
ステップ 6: セキュリティグループの設定
設定画面で以下を選択し、「確認と作成」を押す。
- セキュリティグループの割り当て: 既存のセキュリティグループを選択する
- 最初の手順で作成したJMeter用のセキュリティグループを選択
ステップ 7: インスタンス作成の確認
内容に間違いがないことを確かめて、「起動」を押す。
既存のキーペアを選択または新しいキーペアを作成
既存のキーペアがある場合はそれを選択する。
キーペアが無い場合や新たに作成したい場合は、「新しいキーペアの作成」を選択し、キーペア名を入力してキーペアをダウンロードする。
「インスタンスの作成」を押す。
※ダウンロードしたキーペアをSSHログインで使用する際は、事前にパーミッションの変更が必要。
$ chmod 400 keypair.pem
CentOSの設定
起動したEC2インスタンスにSSHでログイン
$ ssh -i keypair.pem centos@xxx.xxx.xxx.xxx
ログインユーザー名はcentos
になる。
xxx.xxx.xxx.xxxの部分には、インスタンスのIPv4 パブリック IPを入力する。
SELinuxを無効化
$ sudo sed -i -e 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
$ sudo setenforce 0
タイムゾーンを日本に設定
$ sudo cp -p /usr/share/zoneinfo/Japan /etc/localtime
ファイアウォールを無効化
ファイアウォールが動作しているか確認する。
$ sudo systemctl status firewalld
AWSのCentOS 7ではデフォルトで無効のようだが、もし有効だったら以下のコマンドを実行する。
$ sudo systemctl disable firewalld
必要なパッケージをインストール
$ sudo yum -y update
$ sudo yum -y install wget
$ sudo yum -y install java-1.8.0-openjdk.x86_64 java-1.8.0-openjdk-devel.x86_64
$ hash -r
Javaが動作することを確認
$ java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-b04)
OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)
JMeterのインストール
JMeterをダウンロードして展開
$ wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-5.1.1.tgz
$ tar xvzf apache-jmeter-5.1.1.tgz
$ mv apache-jmeter-5.1.1 ~/jmeter
必要に応じてプラグインをインストール
(例)JMeter Plugins Managerを利用してjpgc - Standard Setを入れる場合
# JMeter Plugins Managerの準備
$ wget http://search.maven.org/remotecontent?filepath=kg/apc/cmdrunner/2.2/cmdrunner-2.2.jar -O ~/jmeter/lib/cmdrunner-2.2.jar
$ wget http://search.maven.org/remotecontent?filepath=kg/apc/jmeter-plugins-manager/1.3/jmeter-plugins-manager-1.3.jar -O ~/jmeter/lib/ext/jmeter-plugins-manager-1.3.jar
$ java -cp ~/jmeter/lib/ext/jmeter-plugins-manager-1.3.jar org.jmeterplugins.repository.PluginManagerCMDInstaller
# jpgc - Standard Setのインストール
$ ~/jmeter/bin/PluginsManagerCMD.sh install jpgc-standard
JMeterの設定
ヒープメモリのサイズを変更
$ vi ~/jmeter/bin/jmeter
159G あたりにある
: "${HEAP:="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m"}"
の数値を環境に合わせて増やす。
タイムスタンプのフォーマットを変更
$ vi ~/jmeter/bin/jmeter.properties
531G あたりにある
#jmeter.save.saveservice.timestamp_format=yyyy/MM/dd HH:mm:ss.SSS
のコメントアウトを外す。
keystoreを作成
JMeter 4.0よりjmeter-serverとの通信がSSLで行われるようになり、SSL通信で使用するキーおよび証明書(keystore)の作成が必要になった。
$ LANG=C ~/jmeter/bin/create-rmi-keystore.sh
What is your first and last name?
[Unknown]: # rmi と入力
What is the name of your organizational unit?
[Unknown]: # My unit name と入力
What is the name of your organization?
[Unknown]: # My organisation name と入力
What is the name of your City or Locality?
[Unknown]: # Your City と入力
What is the name of your State or Province?
[Unknown]: # Your State と入力
What is the two-letter country code for this unit?
[Unknown]: # XY と入力
Is CN=rmi, OU=My unit name, O=My organisation name, L=Your City, ST=Your State, C=XY correct?
[no]: # yes と入力
Enter key password for <rmi>
(RETURN if same as keystore password): # 未入力のままEnter
Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore rmi_keystore.jks -destkeystore rmi_keystore.jks -deststoretype pkcs12".
Copy the generated rmi_keystore.jks to jmeter/bin folder or reference it in property 'server.rmi.ssl.keystore.file'
作成したkeystoreファイルをルートフォルダへコピーする。
$ sudo cp ~/rmi_keystore.jks /
JMeterが動作することを確認
$ ~/jmeter/bin/jmeter -v
_ ____ _ ____ _ _ _____ _ __ __ _____ _____ _____ ____
/ \ | _ \ / \ / ___| | | | ____| | | \/ | ____|_ _| ____| _ \
/ _ \ | |_) / _ \| | | |_| | _| _ | | |\/| | _| | | | _| | |_) |
/ ___ \| __/ ___ \ |___| _ | |___ | |_| | | | | |___ | | | |___| _ <
/_/ \_\_| /_/ \_\____|_| |_|_____| \___/|_| |_|_____| |_| |_____|_| \_\ 5.1.1 r1855137
Copyright (c) 1999-2019 The Apache Software Foundation
Slave用のCentOSの設定
OS起動時にjmeter-serverが自動的に起動するよう設定
$ sudo vi /etc/rc.d/rc.local
ファイルの末尾に
/home/centos/jmeter/bin/jmeter-server &
を追加する。
rc.localファイルに実行権限を付与
$ sudo chmod +x /etc/rc.d/rc.local
ファイルディスクリプタの設定を変更
$ sudo vi /usr/lib/systemd/system/rc-local.service
ファイル内の [Service]
の配下に
LimitNOFILE=20480
を追加する。
※数値は環境に合わせて変更する。
補足
この設定によって、高負荷をかけた際に「java.net.SocketException: Too many open files」のエラーが発生することを防ぐ。
jmeter-serverをデーモンプロセスとして起動するのではなく、直接コマンドを打って起動する使い方をしたい場合は、上記の代わりに以下の設定を行う。
$ sudo vi /etc/security/limits.conf
ファイル内に
* soft nofile 20480
* hard nofile 20480
の2行を追加する。
ファイルを保存後、再ログインする。
カーネルパラメータを変更
$ sudo vi /etc/sysctl.conf
ファイル内に
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_fin_timeout=5
の2行を追加する。
ファイルを保存後、以下のコマンドを実行して設定を反映させる。
$ sudo sysctl -p
補足
この設定によって、高負荷をかけた際に「java.net.NoRouteToHostException: 要求アドレスに割り当てられません」のエラーが発生することを防ぐ。
OS再起動後にjmeter-serverが自動的に起動することを確認
$ sudo shutdown -r now
$ ssh -i keypair.pem centos@xxx.xxx.xxx.xxx
$ ps -ax | grep jmeter
4071 ? S 0:00 /bin/sh /home/centos/jmeter/bin/jmeter-server
4074 ? S 0:00 /bin/sh /home/centos/jmeter/bin/jmeter -Dserver_port=1099 -s -j jmeter-server.log
4166 ? Sl 0:02 /usr/bin/java -server -XX:+HeapDumpOnOutOfMemoryError -Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1ReservePercent=20 -Djava.security.egd=file:/dev/urandom -Duser.language=en -Duser.region=EN -jar /home/centos/jmeter/bin/ApacheJMeter.jar -Dserver_port=1099 -s -j jmeter-server.log
$ cat /proc/`pgrep java | head -1`/limits | grep 'open files'
Max open files 20480 20480 files
テスト計画ファイルの配置
jmxファイルを作業PCからCentOSに転送
$ scp -i keypair.pem Test.jmx centos@xxx.xxx.xxx.xxx:/home/centos/
ファイルの配置について
jmxファイルはMaster側にのみ配置すればよい。
CSVファイルを読み込んで使用する場合は、Slave側にもCSVファイルを配置しておく。
その際、テスト計画にはCSVファイルを絶対パスで指定しておき、そのパスにCSVファイルを格納する方がわかりやすい。
相対パスで指定した場合は、Master側ではjmxファイルからの相対位置になるが、Slave側ではルートフォルダからの相対位置になる。
AWSでJMeter用のAMIを保存
EC2ダッシュボードでインスタンスメニューを開く。
JMeter用インスタンスを右クリック→インスタンスの状態→停止を選択する。
確認画面で「停止する」を押す。
再度インスタンスを右クリック→イメージ→イメージの作成を選択する。
イメージ名とイメージの説明の欄に適当な名前(例:jmeter)を入力し、「イメージの作成」を押す。
AMIの保存が終わるまで待つ。
AWSでAMIからSlave用のインスタンスを作成
EC2ダッシュボードでAMIメニューを開く。
作成したAMIを選択して右クリック→作成を選択する。
インスタンスの作成は、最初のインスタンス作成と同じ手順で実施する。
※Slaveを多数作成する場合は、インスタンスの詳細の設定でインスタンス数を増やしておく。
※インスタンスのタグ付けでは、Slave用であることがわかりやすいような値を入力するとよい。
※キーペアは既存のものを使用するとよい。
Master側のJMeterにSlaveのリモートホストを設定
作成したSlave用のインスタンスのパブリックDNSを確認する。
Master用のインスタンスを起動し、SSHでログインする。
以下の設定ファイルを編集する。
$ vi ~/jmeter/bin/jmeter.properties
258G-259G あたりにあるremote_hosts
を以下のように編集する。
remote_hosts=ec2-AAA-AAA-AAA-AAA.compute-1.amazonaws.com:1099,ec2-BBB-BBB-BBB-BBB.compute-1.amazonaws.com:1099...
※AAA-AAA-AAA-AAA などの部分には、Slave用のインスタンスのパブリックDNSの値を入力する。MasterとSlaveが同じサブネット内にあるなら、SlaveのプライベートIPを入力してもよい。
補足
設定ファイルを編集する代わりに、Master側でJMeterを実行する際のオプションにリモートホストの情報を加える方法もある。
(例)
~/jmeter/bin/jmeter -n -t Test.jmx -R ec2-AAA-AAA-AAA-AAA.compute-1.amazonaws.com:1099,ec2-BBB-BBB-BBB-BBB.compute-1.amazonaws.com:1099...
Master側でテスト計画の実行を開始(リモート)
# テストを開始するコマンド
$ ~/jmeter/bin/jmeter -n -t Test.jmx -r
# テストを途中で終了するコマンド
$ ~/jmeter/bin/shutdown.sh
# テストを途中で強制停止するコマンド
$ ~/jmeter/bin/stoptest.sh
以上で基本的な構築は完了です。
参考サイト
本環境構築にあたり、以下のサイトの記事を特に参考に致しました。
ありがとうございました。
- SpotInstanceとJMeterを使って400万req/minの負荷試験を行う | Developers.IO
- Linux サーバでの「Too many open files」対策について - akishin999の日記
- KB Odin: ドメイン数が 256 を超えると、Nginx が "Too many open files" エラーで失敗します
- CentOS7のインストールと設定(サービス、ファイアウォールの有効・無効切り替え等) - UbuntuによるEco Linuxサーバ構築記
- CentOS7 ファイアウォール停止方法 | server-memo.net
- 【ELB】AWS ELBの負荷テストをJMeterServer群でやる【負荷テスト】
- ローカルポートを食いつぶしていた話
- Plugins Manager from Command-Line
- Apache JMeter - User's Manual: Remote (Distributed) Testing