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로 그릴 수 있다.
- ab test 시 -g 옵션으로 실행하여 response time을 파일에 저장: $ ab -n 100 -c 10 -g result.plot https://naver.com/
- 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로 가공하는 주기에 대해서는 다시 고민해봐야겠지만, 대용량 트레픽에 대응할때는 괜찮은 방법인 것 같다.