性能検証を実施する際には、負荷テスト・ツールで負荷をかけるだけではなく、vmstatやiostatなどによるサーバー・リソースのモニタリングが必用です。負荷テスト・ツールとモニタリング・ツールを同時に実行するのにforegoが便利なので、foreogoの使用例をまとめます。
foregoとは?
foregoは複数のプロセスを管理するツールです。同じ作者によるforemanというRubyでかかれたツールのGo実装です。foremanの方が広く使われているのですが、一般的に検証環境はインターネットに接続されておらず、Rubyをインストールするのは手間がかかるのでシングル・バイナリで提供されているforegoを使います。
foregoのインストール
foregoのインストールは、foregoのダウンロードページから圧縮されたファイルをダウンロードし、展開するだけです。debやrpmパッケージもありますが、検証環境を汚さないように、ここでは使用しません。
Procfileの記述
foregoはProcfileというファイルに記述された複数のプロセスを管理します。Procfileには プロセス名: コマンド
という書式で起動するプロセスを記述します。
例えば、cpu、io、iostat、vmstatというプロセスを以下のように記述します。
cpu: ./cpu.sh
io: ./io.sh
iostat: ./iostat.sh
vmstat: ./vmstat.sh
実行
Procfileに定義した全てのプロセスを一度に起動します。Ctrl + Cでforegoを停止すると、起動した全てのプロセスが停止します。
forego start
並列度を変更することもできます。
forego start -c cpu=2,io=0,iostat=0,vmstat=1
タスクの定義例
cpu、ioというタスクは負荷がけのタスクです。
cpu.shはCPU負荷の高い処理です。cpu.shの中身はyes > /dev/null
なので何も出力せず意味は無いのですが、実行時刻と環境変数TEST_CASEで決まるログ・ファイルを作成します。
#!/bin/bash
logfile="log/$(date +%Y_%m_%d_%H_%M_%S)_${TEST_CASE}_cpu_$$.log"
exec &> >(tee "$logfile")
yes > /dev/null
io.shはI/O負荷の高い処理です。io.shはどのディレクトリにファイルを作成するかを環境変数TEMPFILEで指定します。
#!/bin/bash
logfile="log/$(date +%Y_%m_%d_%H_%M_%S)_${TEST_CASE}_io_$$.log"
exec &> >(tee "$logfile")
tempfile="${TEMPFILE:-$HOME/tempfile}"
echo "tempfile is $tempfile"
while :
do
dd if=/dev/zero of="$tempfile" bs=1M count=1024 oflag=direct
done
vmstat、iostatというタスクはそれぞれvmstatとiostatを使ってリソース監視をするタスクです。
#!/bin/bash
logfile="log/$(date +%Y_%m_%d_%H_%M_%S)_${TEST_CASE}_iostat.log"
exec &> >(tee "$logfile")
iostat -t -x 1
#!/bin/bash
logfile="log/$(date +%Y_%m_%d_%H_%M_%S)_${TEST_CASE}_vmstat.log"
exec &> >(tee "$logfile")
vmstat -n -t 1
実行例
$ forego start
forego | starting cpu.1 on port 5000
forego | starting io.1 on port 5100
forego | starting iostat.1 on port 5300
forego | starting vmstat.1 on port 5600
io.1 | tempfile is /home/vagrant/tempfile
vmstat.1 | procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ ---timestamp---
vmstat.1 | r b swpd free buff cache si so bi bo in cs us sy id wa st
vmstat.1 | 6 1 0 82924 7612 304772 0 0 175 2376 162 81 4 2 94 0 0 2017-03-08 09:40:16 UTC
iostat.1 | Linux 2.6.32-642.el6.x86_64 (ol68) 03/08/2017 _x86_64_ (1 CPU)
iostat.1 |
iostat.1 | 03/08/2017 09:40:16 AM
iostat.1 | avg-cpu: %user %nice %system %iowait %steal %idle
iostat.1 | 3.60 0.00 1.97 0.49 0.00 93.93
iostat.1 |
iostat.1 | Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await r_await w_await svctm %util
iostat.1 | sda 0.61 156.37 7.77 38.43 349.25 4754.26 110.46 0.99 21.35 4.01 24.86 0.46 2.11
iostat.1 | dm-0 0.00 0.00 8.08 191.58 347.12 1532.48 9.41 28.50 142.76 4.14 148.61 0.10 1.95
iostat.1 | dm-1 0.00 0.00 0.05 0.00 0.43 0.00 8.00 0.00 0.50 0.50 0.00 0.29 0.00
iostat.1 | dm-2 0.00 0.00 0.06 3.19 0.50 3222.14 991.65 0.00 0.97 1.17 0.96 0.55 0.18
iostat.1 |
vmstat.1 | 3 1 0 82620 7648 304816 0 0 8 950272 3585 2972 76 24 0 0 0 2017-03-08 09:40:17 UTC
iostat.1 | 03/08/2017 09:40:17 AM
iostat.1 | avg-cpu: %user %nice %system %iowait %steal %idle
iostat.1 | 74.75 0.00 25.25 0.00 0.00 0.00
iostat.1 |
iostat.1 | Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await r_await w_await svctm %util
iostat.1 | sda 0.00 0.00 2.02 1874.75 16.16 1919741.41 1022.91 1.71 0.91 0.50 0.91 0.53 99.80
iostat.1 | dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
iostat.1 | dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
iostat.1 | dm-2 0.00 0.00 2.02 1872.73 16.16 1917672.73 1022.91 1.71 0.92 0.50 0.92 0.53 100.00
iostat.1 |
io.1 | 1024+0 records in
io.1 | 1024+0 records out
io.1 | 1073741824 bytes (1.1 GB) copied, 1.1494 s, 934 MB/s
^C | ctrl-c detected
forego | sending SIGTERM to iostat.1
forego | sending SIGTERM to vmstat.1
forego | sending SIGTERM to cpu.1
forego | sending SIGTERM to io.1
$ ls log
2017_03_08_09_40_16__cpu_3412.log 2017_03_08_09_40_16__io_3413.log 2017_03_08_09_40_16__iostat.log 2017_03_08_09_40_16__vmstat.log