Apache Benchによる負荷テスト
Webサーバーのパフォーマンスのチェックをするために負荷テストとして用いるApache Benchmark
の使い方についてまとめています。
ApacheBenchは、Apache HTTP Server
に同梱されています。
abコマンドを使うために、httpdをインストールします。(不要なapacheが入ってしまのが難点です)
$ brew install httpd
使い方
例えば、対象のURLに対して合計100リクエストで、同時に実行するクライアントの数が10の場合は以下のようなコマンドになります。
※自分の管理下にあるサーバーに対してのみお願いします。自分の管理外のサーバーに対しては、負荷を与える攻撃とみなされる場合があります。
$ ab -c 10 -n 100 {対象のURL}
# http://localhost:8000
$ ab -c 10 -n 100 http://localhost:8000
よく指定されるオプションには以下のようなものがあります。
-c : 同時実行するクライアントの数
同時に実行するクライアントの数を指しています。
これは、Apache Bench
が100の並行リクエストを同時に送信することを意味する。
-n : 全リクエストの総数
送信される全リクエストの総数を指します。
-n 1000
とした場合は、テスト全体で1000回のHTTPリクエストが行われることを意味します。
ab -c 100 -n 1000 http://localhost:8000
とした場合は、100のクライアントが同時に動作して、全てのクライアントが送信するリクエスト合計が1000になるように調整します。-c 100 -n 1000
となると、それぞれが平均で10回のリクエストを行うことになります。
ただし、これは理論上の平均値であり、実際のリクエストの分配は完全に均等ではない場合もあります。Apache Bench
は、全てのリクエストが完了するまで新しいリクエストを生成し続けます。
実行結果の見方
hoge.hogehoge.com
という架空のドメインの/api/health
に対してリクエストを行なったとした場合の実行結果の例です。
$ ab -c 10 -n 100 http://hoge.hogehoge.com/api/health
This is ApacheBench, Version 2.3 <$Revision: 1901567 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking return.merchant-dev.io (be patient).....done
Server Software: cloudflare
Server Hostname: hoge.hogehoge.com
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-ECDSA-CHACHA20-POLY1305,256,256
Server Temp Key: ECDH X25519 253 bits
TLS Server Name: hoge.hogehoge.com
Document Path: /api/health
Document Length: 4 bytes
Concurrency Level: 10
Time taken for tests: 4.763 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 73378 bytes
HTML transferred: 400 bytes
Requests per second: 21.00 [#/sec] (mean)
Time per request: 476.264 [ms] (mean)
Time per request: 47.626 [ms] (mean, across all concurrent requests)
Transfer rate: 15.05 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 33 98 38.3 92 196
Processing: 119 345 127.6 336 702
Waiting: 119 345 127.3 336 702
Total: 182 443 138.2 435 839
Percentage of the requests served within a certain time (ms)
50% 435
66% 474
75% 505
80% 529
90% 649
95% 711
98% 829
99% 839
100% 839 (longest request)
テストに要した時間
Time taken for tests: 4.763 seconds
apache bench
を実行して終了した時間であり、合計で4.763秒かかったことになります。もちろん数値が低い方が好ましいです。
リクエストが成功しているか失敗しているか
Complete requests
が全ての総リクエストであり、Failed requests
がそのうちの失敗しているリクエストの数です。
Complete requests: 100
Failed requests: 0
秒間捌けるリクエスト数
Requests per second: 21.00 [#/sec] (mean)
1秒間に21リクエスト捌けていることになります。
リクエストの処理時間
Time per request: 476.264 [ms] (mean)
Time per request: 47.626 [ms] (mean, across all concurrent requests)
Time per request
には2種類あります。
上側のTime per request
(Time per request: 476.264 [ms] (mean))は、サーバーが単一のリクエストを処理するのにかかる平均時間です。つまり、各リクエストがサーバーによって完了するまでにかかった時間の平均値です。この数値は、サーバーの個々のリクエストに対する処理性能を反映しています。
下側のTime per request
(Time per request: 47.626 [ms] (mean, across all concurrent requests))は、並行して行われた全リクエストにわたる平均応答時間です。
この値は、複数のリクエストが同時にサーバーに送信された場合の平均応答時間を示しています。実際には、この数値は「全リクエストの合計応答時間 ÷ (同時リクエスト数 × リクエストの総数)」
で計算されます。
この数値はサーバーが同時に多くのリクエストをどれだけ効率的に処理できるかを示しています。
要するに、最初の数値(476.264ms)は1つのリクエストの処理にかかる時間を表しているのに対し、2番目の数値(47.626ms)はサーバーが同時に処理する複数のリクエストの平均応答時間を表しています。サーバーが複数のリクエストを効率的に処理できる場合、この2番目の数値は通常、1番目の数値よりも小さくなります。
リクエストにCookieを付与する
リクエストにCookieを付与することができます。
例えば、認証状態でないと正常リクエストを返さないAPIもあります。
-C
オプションで"key=value; hoge=example"
の形式でCookieを付与することができます。
# ここではsessionidと、hogeという名称のCookieを付与している
$ ab -c 10 -t 100 -C "sessionid=sessionidtoken; hoge=example" https://hoge.hogehoge.com/api/health
socket: Too many open filesというエラーが出た場合
-c
オプションによる並列数が大きすぎた場合に、socket: Too many open files
というエラーが表示されてしまいます。
$ ab -c 1000 -n 10000 https://hoge.hogehoge.com/api/health
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
socket: Too many open files (1000)
1プロセス
にはリソースを食いつぶさないように、使えるファイルディスクリプタの上限が決まっています。
上限の数値はulimit -n
のコマンドで確認ができます。
$ ulimit -n
500
1000の同時リクエストができるようにしたい場合は、以下のコマンドで上限を設定し直すことができます。
$ ulimit -n 1000
Discussion