この記事は公開から1年以上が経過しています。内容が古い場合があるのでご注意下さい。

負荷テストツールであるSiegeとSproxyで、より実際のアクセス状況に即した負荷テストを行うことができるということで、試してみました。

概要

Sproxyとは、Siegeが読み込む為のURLリストを収集してくれるツールで、Perl製のプロキシサーバです。
このSproxyを使って、以下の流れで負荷テストを行いたいと思います。

1. wgetの再帰ダウンロード機能をSproxy経由で用いて、負荷テスト対象に対するURLを収集します。
2. wgetとsproxyで効率的にURLリストを作成できたら、siegeで負荷テストを行います。

SiegeはURLリストがあると、そのリストの中からランダムにアクセスするので、実際のユーザのブラウジングに近い、リアルなアクセス状況を想定した負荷テストを行うことができるというものです。

参考ページ:Simulate real users load on a webserver using Siege and Sproxy

では、その詳細を確認していきたいと思います。

インストール

環境構築

siegeとsproxyに必要なものをインストールしておきます。

$ sudo yum -y install make gcc-c++ perl-CPAN perl-libwww-perl perl-URI openssl-devel

sproxyに必要なものをインストール

$ sudo perl -MCPAN -e shell
cpan> o conf prerequisites_policy follow
cpan> o conf commit

cpan> install YAML
cpan> install Crypt::SSLeay

Sproxyインストール

$ wget http://download.joedog.org/sproxy/sproxy-latest.tar.gz
$ tar xzvf  sproxy-latest.tar.gz
$ cd sproxy-1.02/
$ ./configure
$ make
$ sudo make install

Siegeのインストール

$ wget http://download.joedog.org/siege/siege-latest.tar.gz
$ tar xzvf  siege-latest.tar.gz
$ cd siege-3.1.4/
$ ./configure
$ make
$ sudo make install

負荷テストの事前準備

Sproxyの起動

まずは、sproxyを起動させます。
sproxyを起動させると、localhostに対して9001番ポートをListenした状態で起動します。

$ sproxy -o ~/urls.txt

SPROXY v1.02 listening on port 9001
...appending HTTP requests to: /home/ec2-user/urls.txt
...default connection timeout: 120 seconds

wgetでURL収集

次に、sproxyをプロキシとして、wgetで負荷テスト対象のサイトをクロールしてURLを収集します。

$ wget -r -o verbose.txt -l 0 -t 1 --spider -w 1 -e robots=on -e "http_proxy = http://127.0.0.1:9001" "http://<Target Web Site>"

-rオプションで再帰的に指定ダウンロードすることで、wgetをクローラとして動かしています。
ちなみに再帰ダウンロードとは、あるページを指定した時に、そのページに含まれているリンク先も再帰的に取得できることを意味します。

wgetのオプション

ここで利用しているwgetのオプションの意味は以下の通りです。

オプション 意味
-r, –recursive 再帰ダウンロードを行う
-o, –output-file=[logfile] ログを[logfile]に出力する
-l, –level=[depth] 再帰時の階層の最大の深さを[depth]に設定する (0で無制限)
-t, –tries=[number] リトライ回数の上限を[number]に指定 (0は無制限)
–spider 何もダウンロードしない
-w, –wait=[seconds] ダウンロード毎に[seconds]秒待つ
-e, –execute=[command] .wgetrc形式のコマンドを実行する

~/.wgetrcが必要な場合は、下記のように書きます。

use_proxy = on
proxy_user = hoge
proxy_passwd = PassWord
http_proxy = http://abcproxy.examlple.com:8080
https_proxy = http://abcproxy.examlple.com:8080
ftp_proxy = http://abcproxy.examlple.com:8080

[-e http_proxy]について

今回は上記の.wgetrcを使わないので、環境変数http_proxyをコマンドライン上で指定しています。

$ wget -e http_proxy=<proxy_host> http://yyyyyyyy
参考ページ

[-e robots=on]について

robots.txtを無視するかしないか、という設定です。onにすることでrobots.txtに従います。
robots.txtというより、厳密にはRobots Exclusion Standardを遵守するという意味合いになります。
https://ja.wikipedia.org/wiki/GNU_Wget

URLリストのユニーク化

sproxy経由で収集したURLには重複しているものがあるので、ユニークにします。

$ sort -u -o uniq_urls.txt urls.txt

負荷テストの実行

下記の意味は、「同時接続ユーザ数は50で、コネクションあたりのリクエスト数が10のアクセスが10秒間来た」という状況を想定しています。
アクセスするURLは、uniq_urls.txtにあるリストからランダムに選ばれます。
尚、-dはリクエスト間の間隔(秒)を指定するものですが、負荷テストにおいてはピーク時を想定するものと思いますので、デフォルトの1としています。

$ siege -d 1 -v -c 50 -i -r 10 -t 10S -f uniq_urls.txt

Transactions:                    434 hits
Availability:                 100.00 %
Elapsed time:                   9.71 secs
Data transferred:               3.65 MB
Response time:                  0.00 secs
Transaction rate:              44.70 trans/sec
Throughput:                     0.38 MB/sec
Concurrency:                    0.16
Successful transactions:         421
Failed transactions:               0
Longest transaction:            0.02
Shortest transaction:           0.00

siegeのオプションと結果の見方

siegeのオプションの意味
オプション 意味
-v,–verbose HTTPレスポンスコード等のアクセス状況を標準出力に出力します。
-c, –concurrent=[NUM] 同時接続ユーザー数を指定
-i, –internet 実際のユーザアクセスのように、URLのリストファイルからランダムにアクセスする
-t, –time=[NUMm] アクセスする(負荷をかける)時間の長さを指定する
(S:秒、M:分、H:時間)
-f, –file=[FILE] アクセスするURLリストのファイルを指定する
-d, –delay=[NUM] リクエスト間の間隔(秒)を指定する。デフォルトは1秒。
(0を指定するとベンチマークモードと同じ結果になる)
-b, –benchmark ベンチマークモード。リクエスト間隔を置かずにアクセスする
(公式には非推奨オプション)
-r, –reps=[NUM] コネクションあたりのリクエスト数

ちなみに、-tオプションは-rオプションよりも優先される為、-rで指定したリクエスト分のアクセスが完了しても、-tで指定した時間の限りアクセスを続けます。

siegeの結果の見方

siegeの結果の各項目の意味は以下の通りです。

項目 意味
Transactions 合計リクエスト数
Availability リクエストの成功率。
(400と500番台のエラーはFailed transactionsに含む)
Elapsed time 全ての負荷テストにかかった時間
Data transferred データ転送量の合計
Response time 各ユーザの1リクエストあたりの平均応答時間
Transaction rate 1秒あたりに処理できたリクエスト数の割合
Throughput 1秒あたりのデータ転送量の平均(byte)
Concurrency 同時接続数の平均
Successful transactions 成功したリクエスト数
(400番未満の応答コードを返したものが対象)
Failed transactions 失敗したリクエスト数
(socket timeoutを含む400番以上の応答コードを返したものが対象)
Longest transaction 1リクエストあたりの処理にかかった最長秒数
Shortest transaction 1リクエストあたりの処理にかかった最短秒数

ログ

デフォルトではPREFIX/var/siege.logに出力されます。
その他の指定方法は、–log[=FILE]オプションを付けるか、.siege/siege.confでlogfile = [FILE]として指定します。

下記のようなログが出ます。

      Date & Time,  Trans,  Elap Time,  Data Trans,  Resp Time,  Trans Rate,  Throughput,  Concurrent,    OKAY,   Failed
2016-03-04 16:31:13,    285,       1.71,           2,       0.02,      166.67,        1.17,        4.02,     271,       0
2016-03-04 16:32:49,    306,       1.13,           2,       0.02,      270.80,        1.77,        5.84,     297,       0

このログは追記型で記録されていきます。

同時接続数の上限

同時接続を255以上にするとエラーになります。

$ siege -v -c 500 -i -t 10S -f uniq_urls.txt -d 10

================================================================
WARNING: The number of users is capped at 255.  To increase this
         limit, search your .siegerc file for 'limit' and change
         its value. Make sure you read the instructions there...
================================================================

対処方法

.siegercをソースからコピーしてlimit = 255の指定を変更します。
もしくは、.siege/siege.confでlimit = 255の指定を変更します。

.siegercファイルを使う場合

ソースに含まれる.siegercをコピーして設定します。

$ cp siege-3.1.4/doc/siegerc ~/.siegerc

siegeの -t オプションと -r オプションの関係

個人的に、-tオプションと-rオプションの関係性がよく分からなかったので、-dオプションではなく、リクエスト間のインターバルの無い-bオプションを使って、動作を確認してみました。

まず簡単に説明すると、両者の違いは以下のとおりです。

$ -b -c500 -t30S
 500ユーザが30秒間絶え間なくアクセス

$ -b -c500 -r30
 500ユーザが30回アクセス。-rはコネクションあたりのリクエスト数

-t オプションで負荷をかけてみる

-rオプション無しの下記の場合だと、5秒間ずっと、URLリストのURLにランダムに、同時接続数100でアクセスし続けます。

$ siege -b -v -c 100 -i -t 5S -f uniq_urls.txt

Transactions:                   6451 hits
Availability:                 100.00 %
Elapsed time:                   4.37 secs
Data transferred:              56.30 MB
Response time:                  0.07 secs
Transaction rate:            1476.20 trans/sec
Throughput:                    12.88 MB/sec
Concurrency:                   98.49
Successful transactions:        6164
Failed transactions:               0
Longest transaction:            0.15
Shortest transaction:           0.01

-r オプションで負荷をかけてみる

-tオプション無しの下記の場合は、同時接続ユーザ数100なので、結果のTransactionsが500リクエストちょうどになっています。
1コネクションあたり5リクエスト投げるので、同時接続ユーザ数コネクションあたりのリクエストを掛けあわせた500リクエストになるという訳です。
webサーバ側のアクセスログにも、ちょうど500行のアクセスログが出力されます。

[同時接続ユーザ数] x [コネクションあたりのリクエスト] = [Transaction数]

$ siege -b -v -c 100 -i -r 5 -f uniq_urls.txt

Transactions:                    500 hits
Availability:                 100.00 %
Elapsed time:                   0.38 secs
Data transferred:               4.68 MB
Response time:                  0.07 secs
Transaction rate:            1315.79 trans/sec
Throughput:                    12.33 MB/sec
Concurrency:                   86.45
Successful transactions:         473
Failed transactions:               0
Longest transaction:            0.13
Shortest transaction:           0.01

-rと-tオプションの両方を併用する

$ siege -v -c 50 -i -r 100 -t 10S -f uniq_urls.txt

この場合は、

同時接続ユーザ数50で、それぞれのコネクションあたり100リクエストを10秒間投げ続ける

という意味になります。

ここで個人的に重要だったのは、以下です。

<ポイント1つ目>
50×100で5000リクエストが完了した時点で10秒以内であれば、また同じリクエストを時間の限り投げ続けます。
そして10秒経過した時点で終了します。
つまり、両方のオプションを使うことで、指定リクエスト分のアクセスが完了しても、時間の限り同じ指定でアクセスを続けます。

<ポイント2つ目>
上記で`-t`オプションを付けなければ、時間を意識すること無く、指定した同時ユーザ数で指定リクエスト数(上記なら5000リクエスト)を処理できたら、負荷をかけるのをやめます。

個人的な結論

どのオプションの組み合わせが最適なのか悩みましたが、より実際のアクセスに近い状態を再現するなら、-bオプションは使わず、とりあえずdelayはデフォルトの1秒の指定のままにした状態で、-r-tオプションを組み合わせるのがよいのでは、と思いました。

AWSなどクラウド環境を使うときは、いつでもリソースを変更できるので、オンプレのような厳密なサイジングはあまり考えなくてもよいのがメリットの1つかと思いますが、本番稼働する際には、こういった方法で簡単にでも、ある程度のあたりをつけてスタートしてみるのも良いんじゃないかと思います。

関連記事:

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です