Apache bench AB test

Apache AB(ApacheBench) 

Apache AB는 Apache Websever의 성능 측정을 위한 Command line Tool로 현재 모든 웹 서버를 테스트할 수 있을 정도로 널리 사용되고있다.

ab 설치

Mac OS인 경우에는 ab는 시스템(/usr/sbin/ab)에 설치되어 있어 별도로 설치할 필요가 없고,우분투인 경우에는 ab  명령어가 실행되지 않는다면  $ sudo apt install apache2-utils 로 설치할 수 있다.

ab 사용법

ab 사용법은 주로 -n (요청 수), -c (동시 호출수) 옵션을 사용해서 호출한다.

$ ab -n 100 -c 10 https://naver.com/

이 명령은 100개의 HTTPS 요청을 실행하고 동시에 최대 10개의 요청을 특정 URL https://naver.com/ 요청한다. 각 명령어 옵션에 대한 설명은 다음과 같다.   Rest API의 GET뿐 만 아니라 POST, PUT 옵션도 테스트 가능하며, -H 옵션으로 Header 설정도 가능하다.

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     (TLS1, TLS1.1, TLS1.2 or ALL)
    -E certfile     Specify optional client certificate chain and private key

ab 주의 사항

AB 테스트 시 주의해야 사항은 다음과 같다.

  • Html이나 CSS, Java script 등의 해석은 하지 않음. 단순히 서버에 대한 응답 시간만 측정 
  • Http 1.0 client를 사용.   
  • request  간의 delay가 없어 서버에서 DDos 공격으로 간주될 수 있음.

참고로, Localhost 테스트 시 “Issue: Invalid argument (22) when running apache bench (ab)” 에러가 발생할 수 있음.  발생 원인은 ab의 URL http://localhost/ 를 사용해서 에러가 발생하는 것으로 http://127.0.0.1/ 으로 URL을 변경하면 정상 동작한다.

ab test 결과를 gnuplot으로 그래프 그리기

ab test 결과를 gnuplot을 활용해서 graph로 그릴 수 있다. 

  1. ab test  시 -g 옵션으로 실행하여 response time을 파일에 저장:  $ ab -n 100 -c 10 -g result.plot https://naver.com/
  2. Response 파일을 gnuplot을 활용해서 그래프로 출력  $ gnuplot script.plot

각 항목의 의미는 다음과 같다.

  • starttime : request가 시작된 시간
  • seconds : starttime을 unix timestamp로 표현
  • ctime : connection 시간으로 request를 write 하기 위해 서버와 socket을 여는 시간
  • dtime : processing 시간 = 결과를 반환받기 위해 wait 하는 시간 + 서버 작업 시간 + 결과 반환 시간  dtime = ttime – ctime
  • ttime : request가 전체 수행된 시간(ttime = ctime + dtime)
  • wait : request를 보내고 나서 response를 받기 전까지 서버사이드에서 처리되는 시간.   network 시간 = dtime – wait

응답값 분석

Document Path:          /
Document Length:        417554 bytes

Concurrency Level:      10
Time taken for tests:   206.995 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      41778600 bytes
HTML transferred:       41755400 bytes
Requests per second:    0.48 [#/sec] (mean)
Time per request:       20699.476 [ms] (mean)
Time per request:       2069.948 [ms] (mean, across all concurrent requests)
Transfer rate:          197.10 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      698  741  16.0    740     775
Processing: 13710 19598 3324.9  18984   28880
Waiting:     2412 3749 609.8   3822    6468
Total:      14431 20339 3322.5  19720   29621

Percentage of the requests served within a certain time (ms)
  50%  19720
  66%  20715
  75%  22093
  80%  22691
  90%  25813
  95%  28246
  98%  29366
  99%  29621
 100%  29621 (longest request)

이런 결과가 있다고 하면, 분석은 아래와 같다.

성능 지표

  • Concurrency Level: 동시에 실행된 요청의 수. 이 경우 10
  • Time taken for tests: 모든 요청을 처리하는 데 걸린 총 시간. 206.995초
  • Complete requests: 성공적으로 완료된 요청 수. 여기서는 100.
  • Failed requests: 실패한 요청 수. 여기서는 0입니다, 즉 모든 요청이 성공적이었음
  • Total transferred: 전송된 총 데이터 양. 약 41.78MB
  • Requests per second: 초당 처리된 요청 수. 여기서는 평균 0.48, 이는 서버가 초당 약 0.48개의 요청을 처리할 수 있음을 의미한다.
  • Time per request: 각 요청을 처리하는 데 걸린 평균 시간. 모든 동시 요청을 고려했을 때 평균 20,699.476ms (약 20.7초)
  • Time per request (mean, across all concurrent requests): 동시 요청 각각에 대한 평균 처리 시간. 2,069.948ms (약 2.07초)
  • Transfer rate: 데이터 전송률. 평균 197.10 KB/sec

연결 시간 (ms)

  • Connect: 요청을 보내기 위해 연결을 설정하는 데 걸린 시간의 통계.
  • Processing: 서버가 요청을 처리하는 데 걸린 시간의 통계.
  • Waiting: 서버가 응답을 생성하는 데까지 기다린 시간의 통계.
  • Total: 요청을 보내고 응답을 받기까지의 총 시간의 통계.

요청 처리 시간

이 테스트 결과는 서버가 처리하는 데 평균적으로 상당한 시간이 소요되고 있음을 보여준다. 특히, 모든 동시 요청에 대한 평균 처리 시간이 20초를 넘는 것은 주목할 만한 부분이다. 이는 서버가 높은 부하 하에서 요청을 처리하는 데 어려움을 겪고 있을 수 있음을 시사한다.

실제 고객사에서 워드프레스 / 우커머스에 많은 플러그인을 붙여서 사용하다보니 너무 낮은 퍼포먼스를 보여서, index.php 를 wget으로 가져온 후에 index.html 로 만들어서 서빙을했더니 엄청난 퍼포먼스 향상이 있었다.

사이트에 접근하는 고객들의 70% 정도는 index로 방문을 할건데, 여기서 많은 db 커넥션이 일어날거고.. 거기에 따른 부하 / 병목현상으로 사이트 퍼포먼스가 엄청 떨어지는거였다. index.html로 가공하는 주기에 대해서는 다시 고민해봐야겠지만, 대용량 트레픽에 대응할때는 괜찮은 방법인 것 같다.