웹 서비스를 구축하고 웹 서버에 동시 접속하는 경우에 대해서 신뢰성과 안정성을 확인할 때 Web Server Benchmaking tool을 사용해서 Load Test를 진행해야 합니다. Web Server에 대한 벤치마킹 테스트 툴은 Apache AB와 JMeter를 활용할 수 있습니다. 본 블로그는 AB를 설명하고자 합니다.
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 test 결과이고, 오른쪽이 flask서버의 로그 출력 결과입니다. Sever host name 함께 전송하는 html 파일의 크기, 반응 속도에 대한 평균, 표준 편차, 최소, 최대 값을 표시합니다. 실행 결과 파일은 -e 옵션을 사용하여 CSV 파일에 저장도 가능합니다. Flask 서버 로그를 보면 Http 1.0을 사용하고 있음 알 수 있고, 요청 시간을 확인할 수 있습니다.
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
$ ab -n 100 -c 10 -g result.plot https://naver.com/ 실행결과를 저장한 result.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
아래 내용을 script.plot으로 저장하고 $ gnuplot script.plot으로 해당 script를 실행합니다. 참고로 gnuplot 설치는 Mac OS에서 % brew install gnuplot으로 설치 가능합니다.
# 터미널 사이즈 조정(이미지 사이즈)
set terminal png size 1024,768
# 가로, 세로 비율
set size 1,0.5
# 결과 파일 설정
set output "result.png"
# 범례/key 위치
set key left top
# y축 grid line
set grid y
# Label the x-axis
set xlabel 'requests'
# Label the y-axis
set ylabel "response time (ms)"
# Tell gnuplot to use tabs as the delimiter instead of spaces (default)
set datafile separator '\t'
# Plot the data
plot "result.plot" every ::2 using 5 title 'response time' with lines
exit
gnuplot script.plot 실행하면 result.png파일로 아래와 같은 graph를 저장할 수 있습니다.
관련 글:
[SW 개발/Python] - Python 가상환경(Virtual Environment) 만들기 위한 virtualenv 명령어 및 실행 예제
[SW 개발/REST API] - 자주 사용하는 curl 명령어 옵션과 예제
[SW 개발/Python] - Python: JSON 개념과 json 모듈 사용법
[SW 개발/REST API] - 외부 망에서 Localhost를 접속하기: localtunnel (무료, domain제공)
[SW 개발/REST API] - 외부 망에서 Localhost를 접속하기: ngrok (일부 무료)
[Cloud/Google Cloud Platform] - GCP에서 Squid를 이용한 Proxy 서버 설정 방법
[SW 개발/REST API] - 라이딩 앱 Strava API 사용해보기: Webhook 구현
[SW 개발/Python] - Python에서 URL 한글 깨짐 현상: quote_plus()와 unquote_plus()
[SW 개발/REST API] - JWT(JSON Web Token) Encoding 방법 (Python sample code)
댓글