Help us understand the problem. What is going on with this article?

Macとtsungで手軽に数千~数万req/sのHTTP負荷テスト

More than 3 years have passed since last update.

今までWebの負荷テストにJMeterを使っていましたが、秒間数百req/sとあまり高負荷をかけられなかったので、こちらの記事を見てtsungを使用することに決めました。
今回は単純に一つのMacクライアントから一つのWebサーバに負荷を掛けてみます。
Macで動かそうとすると色々ハマったので備忘録も兼ねて。

環境

MBP13インチ(Early 2015)
CPU: i7(3.1GHz 物理2コア)
メモリ: 8GB

$ tsung -v
Tsung version 1.6.0

インストール

$ brew install tsung # tsung本体
$ tsung -v
$ sudo cpan Template # Template-Toolkitのインストール
# インストール時の質問は全て[y]または[Enter]で答えれば大丈夫でした

Load Testing Rails 5 Action Cable with Tsungを参考にTemplate-Toolkitをインストールしましたが、それだけでは集計用プログラムを走らせる時に、

Can't locate Template.pm in @INC (you may need to install the Template module) (@INC contains: /Library/Perl/5.18/darwin-thread-multi-2level /Library/Perl/5.18 /Network/Library/Perl/5.18/darwin-thread-multi-2level /Network/Library/Perl/5.18 /Library/Perl/Updates/5.18.2 /System/Library/Perl/5.18/darwin-thread-multi-2level /System/Library/Perl/5.18 /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level /System/Library/Perl/Extras/5.18 .) at /usr/local/lib/tsung/bin/tsung_stats.pl line 570.

というエラーメッセージが表示され、上手く動きませんでした。
brewでperlをインストールしていたので、集計用プログラムのperlのパスが違っていたのが原因でした。
$ which perl/usr/bin/perlと表示された場合は以下の修正は不要です。

$ chmod u+w /usr/local/lib/tsung/bin/tsung_stats.pl # 書込権限付与
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/local/bin/perl -w
$ chmod u-w /usr/local/lib/tsung/bin/tsung_stats.pl # 書込権限削除

負荷テスト設定

負荷テストの設定はxmlファイルへ書き込みます。

$ git clone https://github.com/kurebio/mac-tsung.git
$ vi tsung.xml # テスト先サーバなどを指定
tsung.xml
<?xml version="1.0"?>
<!DOCTYPE tsung SYSTEM "/usr/local/Cellar/tsung/1.6.0/share/tsung/tsung-1.0.dtd">
<tsung loglevel="notice" version="1.0">

<clients>
<client host='localhost' maxusers="500" use_controller_vm="true"/>
</clients>

<servers>
<server host="localhost" port="8000" type="tcp"/>
</servers>

<load>
<arrivalphase phase="1" duration="60" unit="second">
<users maxnumber="500" arrivalrate="100" unit="second"/>
</arrivalphase>
</load>

<sessions>
<session probability="100" name="http-test" type="ts_http">
<for from="1" to="10000" incr="1" var="counter">
<request> <http url="/test.json" method="GET" version="1.1"/> </request>
</for>
</session>
</sessions>

</tsung>

clients

<clients>
<client host='localhost' maxusers="500" use_controller_vm="true"/>
</clients>

ローカルのMacのみをクライアントとして使用します。
maxuser: このクライアントが走らせる最大ユーザー数
use_controller_vm: trueで最大オープンソケット数の問題を解決するためのErlang virtual machineを使用しません。参考

servers

<servers>
<server host="localhost" port="8000" type="tcp"/>
</servers>

localhost:8000へ向けて負荷テストを行います。

load

<load>
<arrivalphase phase="1" duration="60" unit="second">
<users maxnumber="500" arrivalrate="100" unit="second"/>
</arrivalphase>
</load>

arrivalphase: 最初のフェーズで(二つ目以降のフェーズはありませんが)duration秒間アクセスし続けます。
unitにはsecond, minute または hourが入り、現バージョンでは50日弱程度まで設定出来ます。
6.4.3. Duration of the load test

users: 同時アクセスを行う数(ユーザー)を、最大arrivalrateユーザー/unitずつ増やし、maxnumberまで増加させます。
増加量は必ずしもarrivalrateの値になるのではなく、クライアントの負荷によっては増加量が減少します。
最大数は$ ulimit -nの数に依存するので、必要に応じてmacOS Sierraでulimitを変更する方法などで調整しましょう。

durationに達するか、ユーザーがmaxnumberまで達したらユーザーの増加が止まり、全ユーザーのリクエストが完了次第プログラムが終了します。リクエストが終了するまで止まらないため、リクエスト実行時間=durationではありません。

sessions

<sessions>
<session probability="100" name="http-test" type="ts_http">
<for from="1" to="10000" incr="1" var="counter">
<request> <http url="/test.json" method="GET" version="1.1"/> </request>
</for>
</session>
</sessions>

session probability: 100%の確率でこのセッションを使用します(複数セッションがある場合は合計が100になるよう設定します)。
probabilityの変わりにweightを用いると、weight="1"とweight="2"を設定した2つのセッションに、それぞれ1:2の割合でアクセスを割り振る、ということもできます。
Tsungで負荷テストしよう(3) - リアルな負荷のためのTips

for: この場合for(int counter = 1; counter <= 10000, counter++)のような意味です。
counterはリクエストURLに使用出来ます。
<http url="/page?id=%%_counter%%"></http>
その他のループや条件分岐は以下より。
6.7.5. Loops, If, Foreach

request: 1人のユーザーがどのエンドポイントへリクエストするか指定します。

上記内容を総合すると、ローカルサーバのJSONに10,000回アクセスしようとする最大500人のユーザーが毎秒100人くらい現れる、という内容になります。

負荷テスト実行

$ tsung -f ./tsung.xml -l log start # 負荷テスト実行
Starting Tsung
Log directory is: ~/tsung/log/[YYYYMMDD-HHMM]
[os_mon] cpu supervisor port (cpu_sup): Erlang has closed

# 最新のログを集計し、レポートをブラウザで開く 上記負荷テスト実行と繋げても良し
$ cd ./log/`ls -t log | head -n 1` && \
  /usr/local/lib/tsung/bin/tsung_stats.pl && \
  open report.html && \
  cd ../../

結果

Mac→同ホスト内nginxの静的ファイル

Code Highest Rate Mean Rate Total number
200 27133.1 / sec 13299.37 / sec 5000000

自ホストへのリクエストですが、最大秒間27133req/sでリクエストを行えました!

Mac→リモートホスト(ConohaVPS 32G/12v)内nginxの静的ファイル

Code Highest Rate Mean Rate Total number
200 11300.4 / sec 5896.29 / sec 499997

負荷を考え、リクエスト数を1ユーザー当り1,000に減らしました。
この数値はtsungやnginxの限界というより、自宅回線やConohaのネットワークの限界(100Mbps)のようです。
リモート側のCPU使用率は10%くらいで、トラフィックは90Mbps前後でした。
3回ほどエラーで失敗しているのは、回線の逼迫が原因かと思います。

Mac→リモートホスト(ConohaVPS 32G/12v)内Wordpress(初期状態, kusanagi使用, cache未使用)TOPページ

Code Highest Rate Mean Rate Total number
200 857.8 / sec 602.67 / sec 50000

リクエスト数を1ユーザー当り100に減らし、ネットワークの負荷を下げるためテンプレートファイルの出力を3バイトにし、php-fpmのchildrenをmin100~max500に設定しました。
リモート側のCPU使用率は60%弱くらいでした。
この辺りはKUSANAGI for AWSの太い回線で、本番用のプラグインも入れてテストしたいですね。

JMeter参考

ケース max(req/s) mean(req/s)
Mac→ローカル 1055.4 456.3
Mac→リモート静的ファイル 606 346.9
Mac→リモートWordpress 610.9 358.5

まとめ

Macのノート用の低消費電力CPUでも数万req/sを叩き出せて満足です。
設定次第でPOSTリクエスト、認証ページへのアクセス、DBサーバーへのクエリ、レスポンスのチェックなど、自由度の高いテストが出来るので、色々試してみたいです。
今回はMaxを測るため瞬間的にリクエスト数を増やしましたが、実務で使う場合は1週間の間毎秒100人ずつアクセスさせ、たまにユーザー数が10倍になる、といった設定で走らせた方が妥当かもしれません。
VPSなどに負荷を掛ける場合は他の利用者のことも考え、CPUやトラフィックの数値を見ながら大量に長時間リソースを消費しないよう行いましょう。

kurebio
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away