labunix's blog

labunixのラボUnix

ab(Apache HTTP server benchmarking tool)を試してみる。

■ab(Apache HTTP server benchmarking tool)を試してみる。

$ man ab | grep -A 1 NAME
NAME
       ab - Apache HTTP server benchmarking tool

$ ab -V
This is ApacheBench, Version 2.3 <$Revision: 1604373 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

■apache2-utilsパッケージに含まれているバージョンを使用。

$ whereis -b ab | awk '{print "apt-file search "$NF}' | sh | grep apache
apache2-dbg: /usr/lib/debug/usr/bin/ab
apache2-utils: /usr/bin/ab

$ sudo apache2ctl -v
Server version: Apache/2.4.10 (Debian)
Server built:   Nov 28 2015 14:05:48

■リクエスト数(-n)と平行処理数(-c)を指定する。

$ ab -h 2>&1 | grep "  *\-[nc] [a-z]"
    -n requests     Number of requests to perform
    -c concurrency  Number of multiple requests to make at a time

■実際の同時接続数が2000では無い点に注意。

$ ab -n 65535 -c 2000 http://172.31.31.100/
This is ApacheBench, Version 2.3 <$Revision: 1604373 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 172.31.31.100 (be patient)
Completed 6553 requests
Completed 13106 requests
Completed 19659 requests
Completed 26212 requests
Completed 32765 requests
Completed 39318 requests
Completed 45871 requests
Completed 52424 requests
Completed 58977 requests
apr_pollset_poll: The timeout specified has expired (70007)
Total of 64446 requests completed

■プロセス数は1。同時接続数は常に一定では無い。

$ while true ;do \
    echo -n "$(date '+%Y%m%d_%H%M%S')"; \
    netstat -an | awk 'BEGIN{n=0}/:80 *EST/{n+=1}END{printf ",%s,",n}'; \
    ps -ef | awk 'BEGIN{c=0}/a[b] -n/{c+=1}END{print c}'; \
    sleep 0.5; \
  done | tee -a check.log
20160328_010317,443,1
20160328_010318,452,1
20160328_010319,590,1
20160328_010320,639,1
20160328_010321,624,1
20160328_010322,519,1
20160328_010323,831,1
20160328_010324,885,1
20160328_010325,805,1
20160328_010326,1104,1
20160328_010326,1261,1
20160328_010327,818,1
20160328_010328,542,1
20160328_010329,799,1
20160328_010331,965,1
20160328_010332,895,1
20160328_010333,867,1
20160328_010333,1089,1
20160328_010334,1089,1
20160328_010335,1089,1
20160328_010335,1435,1
20160328_010336,1435,1
20160328_010337,1435,1
20160328_010337,1435,1
20160328_010338,1435,1
20160328_010339,1435,1
20160328_010339,1435,1
20160328_010340,1435,1
20160328_010341,1435,1
20160328_010341,1435,1
20160328_010342,1435,1
20160328_010343,1435,1
20160328_010343,1435,1
20160328_010344,1435,1
20160328_010345,1435,1
20160328_010345,1435,1
20160328_010346,1435,1
20160328_010347,1435,1
20160328_010347,1435,1
20160328_010348,1434,1
20160328_010348,1433,1
20160328_010349,1430,1
20160328_010350,1429,1
20160328_010350,1429,1
20160328_010351,1429,1
20160328_010352,1429,1
20160328_010352,1429,1
20160328_010353,1429,1
20160328_010354,1429,1
20160328_010354,1429,1
20160328_010355,1429,1
20160328_010356,1429,1
20160328_010356,1429,1
20160328_010357,1429,1
20160328_010358,1429,1
20160328_010358,1429,1
20160328_010359,1429,1
20160328_010400,1429,1
20160328_010400,1429,1
20160328_010401,1429,1
20160328_010402,1429,1
20160328_010402,1429,1
20160328_010403,1429,1
20160328_010404,1429,1
20160328_010404,1429,1
20160328_010405,1429,1
20160328_010406,0,0
20160328_010406,0,0
20160328_010407
^C

■同時接続数は平均1244。
 欲しい同時接続数の約1.62倍が並列数になる想定。

$ awk -F, 'BEGIN{a=0;i=9999}\
                {if($2>0){cnt+=1;sum+=$2;if(a<$2){a=$2};if(i>=$2)i=$2}}\
           END  {print "Total:"sum,"Count:"cnt,"AVG:"sum/cnt,"max:"a,"min:"i}' \
    check.log
Total:82164 Count:66 AVG:1244.91 max:1435 min:443


$ awk -F, 'BEGIN{a=0;i=9999}\
                {if($2>0){cnt+=1;sum+=$2;if(a<$2){a=$2};if(i>=$2)i=$2}} \
           END  {print "Total:"sum,"Count:"cnt,"AVG:"sum/cnt,"max:"a,"min:"i}' \
    check.log
Total:82164 Count:66 AVG:1244.91 max:1435 min:443100%未満の時にしか使えない計算式どの位の指定が必要かを計算。

$ echo "1244 2000" | \
    awk '{a=($1/$2*100);b=(1+(a/100))*$2}\
         END{print a"%\n"1+(a/100)"\nab -n 65535 -c "b}'
62.2%
1.622
ab -n 65535 -c 3244

■「-c 3244」で再テストしてみる。

$ ab -n 65535 -c 3244 http://172.31.31.100/
This is ApacheBench, Version 2.3 <$Revision: 1604373 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 172.31.31.100 (be patient)
Completed 6553 requests
Completed 13106 requests
Completed 19659 requests
Completed 26212 requests
Completed 32765 requests
Completed 39318 requests
Completed 45871 requests
Completed 52424 requests
Completed 58977 requests
apr_socket_recv: Connection reset by peer (104)
Total of 64490 requests completed

$ while true ;do \
    echo -n "$(date '+%Y%m%d_%H%M%S')"; \
    netstat -an | awk 'BEGIN{n=0}/:80 *EST/{n+=1}END{printf ",%s,",n}'; \
    ps -ef | awk 'BEGIN{c=0}/a[b] -n/{c+=1}END{print c}'; \
    sleep 0.5; \
  done | tee check.log
20160328_011337,0,0
20160328_011338,0,0
20160328_011338,0,0
20160328_011339,0,0
20160328_011339,0,0
20160328_011340,315,1
20160328_011340,1000,1
20160328_011341,789,1
20160328_011342,2480,1
20160328_011343,2957,1
20160328_011344,2840,1
20160328_011345,2462,1
20160328_011346,2138,1
20160328_011347,2329,1
20160328_011348,2170,1
20160328_011349,2404,1
20160328_011350,2113,1
20160328_011351,2139,1
20160328_011352,1565,1
20160328_011353,1863,1
20160328_011354,2231,1
20160328_011355,2107,1
20160328_011356,2392,1
20160328_011357,2408,1
20160328_011357,2200,1
20160328_011358,2126,1
20160328_011359,2076,1
20160328_011359,2050,1
20160328_011400,1970,1
20160328_011401,0,0
20160328_011401,0,0
20160328_011402,0,0
^C

■ほぼ計算通り。

$ awk -F, 'BEGIN{a=0;i=9999}\
                {if($2>0){cnt+=1;sum+=$2;if(a<$2){a=$2};if(i>=$2)i=$2}} \
           END  {print "Total:"sum,"Count:"cnt,"AVG:"sum/cnt,"max:"a,"min:"i}' \
    check.log
Total:49124 Count:24 AVG:2046.83 max:2957 min:315

■リクエスト数は割りきれなくても良い想定だけど、
 あえて整数倍を指定するなら以下で求める。

$ echo "65535 3244" | awk '{print $1/$2,$2*21,$2*21}'
20.2019 68124 68124

$ ab -n 68124 -c 3244 http://172.31.31.100/
This is ApacheBench, Version 2.3 <$Revision: 1604373 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 172.31.31.100 (be patient)
Completed 6812 requests
Completed 13624 requests
Completed 20436 requests
Completed 27248 requests
Completed 34060 requests
Completed 40872 requests
Completed 47684 requests
Completed 54496 requests
Completed 61308 requests
apr_socket_recv: Connection reset by peer (104)
Total of 66192 requests completed

$ awk -F, 'BEGIN{a=0;i=9999}\
                {if($2>0){cnt+=1;sum+=$2;if(a<$2){a=$2};if(i>=$2)i=$2}}\
           END  {print "Total:"sum,"Count:"cnt,"AVG:"sum/cnt,"max:"a,"min:"i}' \
    check.log
Total:65736 Count:32 AVG:2054.25 max:2949 min:247

■トータルリクエストに対しての成功率と失敗率ということで良いのかな。。。
 apache2側のログの数とも異なるので、
 タイムアウト値等の調整が必要みたい。。。

$ echo "66192 68124" | awk '{print $1/$2*100"\n"(1-$1/$2)*100}'
97.164
2.836

$ awk '!/0,0/' check.log | awk '{if(NR==1){print}else{a=$0}}END{print a}'
20160328_013848,280,1
20160328_013913,2931,1

$ sudo awk '/01:3[89]/{a[$(NF-3)]+=1}END{for (n in a){print a[n],n}}' /var/log/apache2/access.log 
67812 200

$ echo "67812 68124" | awk '{print $1/$2*100"\n"(1-$1/$2)*100}'
99.542
0.457988

■「-t」を付けると、そもそも結果が異なるので、後日検討し直し。

$ ab -t 10 -n 65535 -c 2000 http://172.31.31.100/
This is ApacheBench, Version 2.3 <$Revision: 1604373 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 172.31.31.100 (be patient)
Completed 6553 requests
Completed 13106 requests
Completed 19659 requests
Completed 26212 requests
Completed 32765 requests
Completed 39318 requests
Completed 45871 requests
Finished 47129 requests


Server Software:        Apache/2.4.10
Server Hostname:        172.31.31.100
Server Port:            80

Document Path:          /index.html
Document Length:        11104 bytes

Concurrency Level:      2000
Time taken for tests:   10.006 seconds
Complete requests:      47129
Failed requests:        0
Total transferred:      538226708 bytes
HTML transferred:       525253630 bytes
Requests per second:    4710.02 [#/sec] (mean)
Time per request:       424.626 [ms] (mean)
Time per request:       0.212 [ms] (mean, across all concurrent requests)
Transfer rate:          52529.12 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0  228 634.7     21    7033
Processing:     2  120 290.2     50    6679
Waiting:        1   98 287.4     28    6666
Total:         11  348 708.2     78    7083

Percentage of the requests served within a certain time (ms)
  50%     78
  66%    114
  75%    178
  80%    289
  90%   1112
  95%   1563
  98%   3072
  99%   3254
 100%   7083 (longest request)