Web Stress / Server Load Testing tool
여러가지 IT 인프라 관련 업무를 진행하다 보면 웹 개발자든, 운영자든 누가 되었든 본인이 만든 서비스의 성능을 측정해야 할 일이 있다. 예를 들어 간단한 웹 사이트 프로젝트를 하나 한다면 해당 웹 사이트가 어느정도 요청까지 한대의 서버에서 견딜수 있는지를 정확하게 알아야만 서버를 확장해 나가는 기준으로 삼을수 있을것이고 이를 통해서 고객에게 서비스 하기 위한 최적의 응답시간도 찾아 낼수 있을것이다.
그럴때 사용하기 좋은 툴을 몇가지 소개 하고자 한다.
% 본 글에서는 간단하면서도 충분히 성능을 검증할 수 있는 툴에 초점을 맞추고 있으므로 상세한 기능에 대해서는 직접 테스트를 해보고 사용하기를 권장한다.
베지터는 큰 설정 없이 일정 비율 (Ex. 초당 몇개)로 웹 서버에 요청을 보내는 테스트를 진행할수 있게 해주는 툴로서 쉽게 설치가 가능하면서도 쓸만한 리포트를 추출 해 준다. 만약 빠르게 웹 서버에 대해서 테스트를 진행해야 할 일이 있을때 사용할 수 있다.
#brew update && brew install vegeta
(brew를 이용하여 간단하게 설치 가능하다.)
% 간단 사용법
#echo "GET http://대상URL" | vegeta attack -rate=10 -duration=100s | vegeta report
간단하게 위와 같은 명령어만으로도 서버의 부하 테스트를 할 수 있고 조절 해야 하는 몇가지 옵션은 아래와 같다.
-rate=10
: 초당 몇개의 요청을 보낼 것인지를 정할 수 있다.
-duration
: 얼마나 요청 할 것인지를 정할 수 있다. ( Ex 100s, 1m, 10m )
-insecure
: 잘못된 TLS 인증서를 무시한다.
-keepalive
: HTTP 요청시에 TCP 연결을 재사용 할지를 결정한다.
- 이외에 더 많은 옵션이 있고 분산하여 요청을 할수도 있다.
% 그래픽한 그래프 결과 그리기
베지터는 터미널 환경에서 그래프를 그리도록 지원해주며 아래 두가지 모듈을 Mac에 설치한 이후 간단하게 명령어를 통해서 그래피컬한 결과값을 볼 수 있다.
그래프를 그리기 위한 모듈 설치
#brew install rs/tap/jplot
#brew install rs/tap/jaggr
명령어
echo 'GET http://example.com/digitco/index.html' | \
vegeta attack -rate 200 -duration 1m | vegeta encode | \
jaggr @count=rps \
hist\[100,200,300,400,500\]:code \
mean,p25,p50,p95:latency \
sum:bytes_in \
sum:bytes_out | \
jplot rps+code.hist.100+code.hist.200+code.hist.300+code.hist.400+code.hist.500 \
latency.mean+latency.p95+latency.p50+latency.p25 \
bytes_in.sum+bytes_out.sum
이제 실질적인 사용을 해보자. 간단하게 두개의 페이지를 준비한다. A는 몇 바이트로 이루어진 단순 HTML 페이지이고 한개는 B. 일반적인 웹 사이트를 구현하였다.
A. #echo "GET http://example.com/" | vegeta attack -rate=10 -duration=100s | vegeta report
Requests [total, rate, throughput] 1000, 10.01, 10.01
Duration [total, attack, wait] 1m40s, 1m40s, 7.455ms
Latencies [min, mean, 50, 90, 95, 99, max] 5.253ms, 27.428ms, 7.217ms, 82.056ms, 155.236ms, 223.606ms, 2.232s
Bytes In [total, mean] 667000, 667.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:1000
초당 10개 수준의 요청을 100초동안 하였다. 총 요청 1000개가 모두 200 OK가 떨어진것을 볼수 있고 레이턴시의 최소,평균,최대값을 확인 할수 있다. 초당 10개의 요청으로는 큰 영향 없이 서비스가 가능한 서버라고 알수 있다.
그렇다면 이제는 요청을 초당 2000개로 변경해서 60초 동안 부하를 주어 보자.
echo 'GET http://example.com/' | vegeta attack -rate 2000 -duration 1m | vegeta report
Requests [total, rate, throughput] 120000, 2000.02, 1012.13
Duration [total, attack, wait] 1m16s, 59.999s, 15.95s
Latencies [min, mean, 50, 90, 95, 99, max] 18.109µs, 122.063ms, 79.046ms, 240.114ms, 381.163ms, 924.737ms, 30.006s
Bytes In [total, mean] 51272290, 427.27
Bytes Out [total, mean] 0, 0.00
Success [ratio] 64.06%
Status Codes [code:count] 0:43130 200:76870
Error Set:
Get "http://example.com/": dial tcp 0.0.0.0:0->example.com:80: socket: too many open files
Get "http://example.com/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
전체 요청의 64%만 성공 하였고 나머지 요청은 서버에서 처리하지 못했다는 것을 알수 있다. 그렇다면 위의 200 OK가 나온 76,870건을 60초로 나누어 보면 초당 1,281개가 나온다.. 그렇다면 정말 저 페이지에 1,200개를 보내보자..
Success [ratio] 94.43%
Status Codes [code:count] 0:4007 200:67993
네트워크의 상황에 따라 틀리겠지만.. 1,200개의 요청을 60초 동안 총 72,000번 요청 했을때 94%의 성공율을 보였다. 실질적으로 아무것도 없는 페이지이므로 이러한 결과가 나왔고 100%가 되는 최대 요청은 초당 400개 수준으로 나왔다. 500개 이상부터는 유실이 발생한다.
이제는 어느정도 내용이 있는 페이지를 예로 들어 보자. 아래와 같이 50개를 1분 동안 총 3,000번 요청 했을때에는 정상적으로 요청이 모두 처리 되었다.
B. #echo 'GET http://example.com/digitco/index.html' | vegeta attack -rate 50 -duration 1m | vegeta report
Requests [total, rate, throughput] 3000, 50.02, 50.01
Duration [total, attack, wait] 59.987s, 59.977s, 9.909ms
Latencies [min, mean, 50, 90, 95, 99, max] 8.147ms, 26.069ms, 14.656ms, 52.334ms, 86.796ms, 185.186ms, 815.405ms
Bytes In [total, mean] 45225000, 15075.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:3000
Error Set:
하지만 초당 2,000개로 올렸을때에는 아래와 같이 26%의 요청만이 성공 하였다. 즉 31,277개만 성공하였고 이를 초로 나눈다면 약 500개 정도의 요청만 받아 준것으로 알수 있다.
echo 'GET http://example.com/digitco/index.html' | vegeta attack -rate 2000 -duration 1m | vegeta report
Requests [total, rate, throughput] 120000, 2000.03, 479.12
Duration [total, attack, wait] 1m5s, 59.999s, 5.281s
Latencies [min, mean, 50, 90, 95, 99, max] 17.872µs, 125.521ms, 95.413µs, 397.993ms, 553.363ms, 972.701ms, 21.417s
Bytes In [total, mean] 471500775, 3929.17
Bytes Out [total, mean] 0, 0.00
Success [ratio] 26.06%
Status Codes [code:count] 0:88723 200:31277
Error Set:
Get "http://example.com/digitco/index.html": dial tcp 0.0.0.0:0->example.com:80: socket: too many open files
간단하게 웹 서버 부하를 테스트 하는 오픈소스 솔루션으로 여러가지 용도에 사용할수 있다. 물론 기능이 많은 프로그램이 더 많은 정보를 줄수 있지만 빠르게 테스트를 할때에는 편리하게 사용이 가능하다.
% 위의 테스트 결과는 테스트를 실시한 환경에 따라 상이할수 있고 상세한 정보를 제공하는 전문적인 성능 측정툴과는 결과값이나 여러가지가 틀릴수 있다.
Latency의 위의 각 수치에 대한 상세한 설명은 아래의 주소를 참고하기 바란다.
https://bravenewgeek.com/everything-you-know-about-latency-is-wrong/
참고 사이트
https://github.com/tsenart/vegeta
https://jmeter.apache.org/index.html
3. nGrinder
https://github.com/naver/ngrinder
참고 사이트
https://testguild.com/open-source-performance-testing-tools/
% 본인이 개발한 사이트가 아닌 외부의 공개된 사이트에 대한 Load Test는 DDoS 공격으로 간주될 수 있고 이로인해 서비스에 영향이 갈수 있으므로 절대 해서는 안됩니다.
% 본 글은 특정 단체나 기업과는 무방한 글입니다.