CLOVER🍀

That was when it all began.

Apache Bench(ab)を試す

Apache BenchというApacheに付属するベンチマークツールですが、名前や使い方はよく見るものの、実際に自分で
使ったことがなかったのでちょっと試してみることにしました。

https://httpd.apache.org/docs/2.4/programs/ab.html

Apache Bench?

ドキュメントの通り、Apache Webサーバーに対するベンチマークツールです。

ab is a tool for benchmarking your Apache Hypertext Transfer Protocol (HTTP) server.

HTTPでの負荷をかけることができる、簡易的なツールのようです。

インストール

Apacheがインストールされている場合、Apache Benchも一緒にインストールされています。

また、Apache自体はインストールせずに、Apache Benchを使いたいという場合は、ユーティリティ的なパッケージを
インストールすることでも導入可能です。

Ubuntu Linuxの場合、以下のコマンドでインストールできます。

$ sudo apt install apache2-utils

今回は、Apache 2.4.29に付属しているApache Benchを使うことにします。

使い方

まずは、ヘルプを。

$ ab -h
Usage: ab [options] [http[s]://]hostname[:port]/path
Options are:
    -n requests     Number of requests to perform
    -c concurrency  Number of multiple requests to make at a time
    -t timelimit    Seconds to max. to spend on benchmarking
                    This implies -n 50000
    -s timeout      Seconds to max. wait for each response
                    Default is 30 seconds
    -b windowsize   Size of TCP send/receive buffer, in bytes
    -B address      Address to bind to when making outgoing connections
    -p postfile     File containing data to POST. Remember also to set -T
    -u putfile      File containing data to PUT. Remember also to set -T
    -T content-type Content-type header to use for POST/PUT data, eg.
                    'application/x-www-form-urlencoded'
                    Default is 'text/plain'
    -v verbosity    How much troubleshooting info to print
    -w              Print out results in HTML tables
    -i              Use HEAD instead of GET
    -x attributes   String to insert as table attributes
    -y attributes   String to insert as tr attributes
    -z attributes   String to insert as td or th attributes
    -C attribute    Add cookie, eg. 'Apache=1234'. (repeatable)
    -H attribute    Add Arbitrary header line, eg. 'Accept-Encoding: gzip'
                    Inserted after all normal header lines. (repeatable)
    -A attribute    Add Basic WWW Authentication, the attributes
                    are a colon separated username and password.
    -P attribute    Add Basic Proxy Authentication, the attributes
                    are a colon separated username and password.
    -X proxy:port   Proxyserver and port number to use
    -V              Print version number and exit
    -k              Use HTTP KeepAlive feature
    -d              Do not show percentiles served table.
    -S              Do not show confidence estimators and warnings.
    -q              Do not show progress when doing more than 150 requests
    -l              Accept variable document length (use this for dynamic pages)
    -g filename     Output collected data to gnuplot format file.
    -e filename     Output CSV file with percentages served
    -r              Don't exit on socket receive errors.
    -m method       Method name
    -h              Display usage information (this message)
    -I              Disable TLS Server Name Indication (SNI) extension
    -Z ciphersuite  Specify SSL/TLS cipher suite (See openssl ciphers)
    -f protocol     Specify SSL/TLS protocol
                    (SSL2, TLS1, TLS1.1, TLS1.2 or ALL)

ポイントとなるオプションは、

  • -n(requests) … 総リクエスト数
  • -c(concurrency) … 同時リクエスト数
  • -t(timelimit) … ベンチマークを実行する最大時間(総リクエスト数に達していなくても、この時間で打ち切る。デフォルトは制限時間なし)
  • -p (postfile) … POST時に送信する内容(HTTPボディ)を記載したファイルを指定
  • -u(putfile) … PUT時に送信する内容(HTTPボディ)を記載したファイルを指定
  • -T(content-type) … POSTやPUTを行う時のContent-Typeを指定(デフォルトは「text/plain」)
  • -H … 追加のHTTPヘッダを指定
  • -A … Basic認証を利用する際のユーザ名とパスワードを指定(「:」で区切る)
  • k … Keep-Aliveを使用する

といったところでしょうか。

Apache JMeterなどであるような、Ramp-Up期間(すべてのクライアントを起動させるまでの時間)はなく、いきなり
指定の同時リクエスト数でアクセスしようとします。

また、URLは単一指定なので、ページを順次遷移していくようなシナリオのようなことはできませんし、途中で
パラメータを変えるようなこともできません。

「-cで指定した同時リクエスト数」がユーザー数の見立てとなり、「-nで指定した値」を「-cで指定した値」で割ったものが、
ユーザーが実行するリクエスト数、ということになります。

リクエストとリクエストの間のwait的な時間も設定できないようなので、本当に一斉にリクエストを投げる感じに
なりますね。なるほど…。

例えば、以下の指定だと同時リクエスト数10で、それぞれが10,000回リクエストを実行することになる、と。

$ ab -n 100000 -c 10 http://...

試してみる

それでは、実際に試してみましょう。

対象のサーバーは、Apacheとします。Ubuntu LinuxでインストールできるApache、デフォルトのままです。

f:id:Kazuhira:20190102233540p:plain

対象のサーバーのIPアドレスは、172.17.0.3とします。

では、同時アクセス数10、総リクエスト数100,000で実行。

$ ab -n 100000 -c 10 http://172.17.0.3/
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 172.17.0.3 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requests


Server Software:        Apache/2.4.29
Server Hostname:        172.17.0.3
Server Port:            80

Document Path:          /
Document Length:        10918 bytes

Concurrency Level:      10
Time taken for tests:   9.074 seconds
Complete requests:      100000
Failed requests:        0
Total transferred:      1119200000 bytes
HTML transferred:       1091800000 bytes
Requests per second:    11019.96 [#/sec] (mean)
Time per request:       0.907 [ms] (mean)
Time per request:       0.091 [ms] (mean, across all concurrent requests)
Transfer rate:          120444.75 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       9
Processing:     0    1   0.3      1      14
Waiting:        0    0   0.3      0      14
Total:          0    1   0.4      1      15

Percentage of the requests served within a certain time (ms)
  50%      1
  66%      1
  75%      1
  80%      1
  90%      1
  95%      1
  98%      1
  99%      2
 100%     15 (longest request)

ざっくり結果を見てみましょう。

「Complete requests」が実行したリクエスト数で、「Failed requests」が失敗したリクエスト数です。今回は、失敗した
リクエストはありません。

Complete requests:      100000
Failed requests:        0

HTTPステータスコードが2xx以外の応答を返した場合は、「Non-2xx responses」がカウントされて表示されます。

Non-2xx responses:      5000

1秒あたりのリクエスト数。今回は、11,019 request / secです。

Requests per second:    11019.96 [#/sec] (mean)

リクエストごとの平均時間。この値は、「Time taken for tests(テストにかかった時間(sec)」 × 1000 / done(Complete requests)で
算出されます。とっても単純。

Time per request:       0.091 [ms] (mean, across all concurrent requests)

なお、こっちの方は「concurrency(-n)」 × 「Time taken for tests(テストにかかった時間(sec)」 × 1000 / done(Complete requests)で
算出されます。

Time per request:       0.907 [ms] (mean)

ところで、アクセスログを見る限り、Apache BenchはHTTP/1.0でアクセスするようですね。

172.17.0.2 - - [02/Jan/2019:14:37:29 +0000] "GET / HTTP/1.0" 200 11192 "-" "ApacheBench/2.3"

とりあえず、使い方はなんとなくわかりました。