부하 테스트 그리고 k6
부하테스트 도구
부하 테스트 툴 비교 및 분석
부하 테스트는 시스템의 성능을 확인하고 병목 현상을 파악하는 데 중요한 역할을 합니다. 다양한 부하 테스트 툴이 존재하며, 각 툴마다 고유한 특징과 장점, 제공하는 메트릭이 있습니다. 이번 글에서는 대표적인 부하 테스트 툴들을 소개하고, 이 글은 k6의 사용법을 중점적으로 설명하겠습니다.
부하 테스트 툴 비교
1. k6
특징
- OAS 플러그인: k6는 OpenAPI Specification(OAS)을 통해 API 테스트를 자동화할 수 있는 플러그인을 제공합니다. 이를 통해 OpenAPI 스펙에 맞춘 테스트를 손쉽게 작성할 수 있습니다.
- JavaScript로 스크립트 작성: k6는 JavaScript를 사용해 테스트 스크립트를 작성할 수 있어, 기존에 JavaScript에 익숙한 개발자에게 유리합니다.
- 분산 부하 테스트: k6는 분산 부하 테스트를 지원하여 여러 대의 머신을 이용해 테스트를 실행할 수 있습니다.
장점
- 사용 편리성: JavaScript 기반으로 스크립트를 작성할 수 있어 빠르게 테스트를 구성할 수 있습니다.
- 성능: 가벼운 CLI 기반으로 빠른 속도와 효율성을 제공합니다.
단점
- UI 제공 부족: 기본적으로 웹 UI를 제공하지 않으며, 결과를 보기 위해서는 CLI 명령어로만 확인할 수 있습니다.
제공하는 메트릭
- HTTP 요청/응답 시간
- 성공률, 실패율
- VUS(가상 사용자)의 수
- 초당 요청 수
- 네트워크 지연 시간
2. Apache JMeter
특징
- 강력한 GUI 지원: JMeter는 GUI 기반으로 사용자가 테스트를 시각적으로 설계할 수 있습니다.
- 다양한 프로토콜 지원: HTTP뿐만 아니라, FTP, JDBC, JMS, LDAP 등 다양한 프로토콜을 지원합니다.
- 분산 테스트 기능: 여러 대의 머신을 이용해 부하 테스트를 분산하여 실행할 수 있습니다.
장점
- 시각적인 설계: GUI로 테스트 시나리오를 쉽게 만들 수 있어 직관적입니다.
- 풍부한 플러그인과 확장성: 다양한 플러그인과 스크립트를 통해 기능을 확장할 수 있습니다.
단점
- 무겁고 느린 성능: GUI 기반이기 때문에, 시스템 리소스를 많이 사용하고 대규모 테스트에 다소 느릴 수 있습니다.
- 복잡한 설정: 초보자에게는 설정이 어려울 수 있습니다.
제공하는 메트릭
- 응답 시간
- 스루풋
- 성공률, 실패율
- 초당 요청 수
- 히스토그램, 분포 차트 등 상세 통계
3. Locust
특징
- Python 스크립트 기반: Locust는 Python을 이용해 부하 테스트 스크립트를 작성할 수 있습니다. 이는 Python에 익숙한 개발자에게 유리합니다.
- 분산 테스트: 여러 대의 머신에서 테스트를 실행할 수 있으며, 이를 통해 대규모 부하 테스트를 수행할 수 있습니다.
- Web UI 제공: 실시간으로 테스트 진행 상황을 웹 UI에서 확인할 수 있습니다.
장점
- Python 코드로 유연한 테스트 시나리오 작성: Python을 활용하여 매우 유연하게 테스트 시나리오를 작성할 수 있습니다.
- 간단한 설치와 사용법: 설치가 간단하고, 테스트 스크립트도 비교적 직관적입니다.
단점
- 기능이 상대적으로 적음: JMeter나 k6에 비해 기본 제공되는 기능이 적고, 커스터마이징이 필요할 수 있습니다.
제공하는 메트릭
- 응답 시간
- 초당 요청 수
- 성공률
- 에러 발생율
4. Gatling
특징
- Scala 기반: Gatling은 Scala로 작성된 테스트 스크립트를 사용합니다. 이는 고급 사용자가 성능 최적화를 위해 코드를 세밀하게 작성할 수 있게 도와줍니다.
- 모델 기반의 부하 생성: Gatling은 테스트 시나리오를 모델링하여 실제와 유사한 트래픽을 생성합니다.
- 비디오 및 HTML 리포트: Gatling은 테스트 결과를 HTML 리포트로 제공하며, 시각적으로 보기 쉽습니다.
장점
- 고성능: 대규모 부하 테스트에서 뛰어난 성능을 보입니다.
- 사용 편리한 리포트: 리포트가 시각적으로 잘 구성되어 있으며, 성능 분석을 쉽게 할 수 있습니다.
단점
- 학습 곡선: Scala를 사용하기 때문에, Scala에 익숙하지 않은 사람은 진입 장벽이 있을 수 있습니다.
- UI가 부족함: Gatling은 기본적으로 웹 UI를 제공하지 않으며, HTML 리포트로 결과를 분석합니다.
제공하는 메트릭
- 응답 시간
- 스루풋
- 에러율
- 경과 시간, 초당 요청 수
5. Artillery
특징
- Node.js 기반: Artillery는 Node.js로 작성된 부하 테스트 툴로, JavaScript 또는 YAML로 스크립트를 작성할 수 있습니다.
- 분산 테스트 지원: Artillery는 클라우드 또는 로컬에서 여러 인스턴스를 실행하여 분산 테스트를 지원합니다.
- 리얼타임 결과 시각화: 테스트 중 실시간으로 메트릭을 시각화할 수 있는 기능을 제공합니다.
장점
- 사용 용이성: JavaScript나 YAML을 사용해 간단한 스크립트를 작성할 수 있습니다.
- 고성능: Artillery는 효율적으로 설계되어 대규모 테스트를 빠르게 수행할 수 있습니다.
단점
- 기능이 상대적으로 제한적: k6나 JMeter에 비해 제공되는 기능이 비교적 적습니다.
제공하는 메트릭
- 초당 요청 수
- 응답 시간
- 성공률
- 에러율
k6 설명
여러 부하 테스트 도구중 k6 에 대한 설명 및 실행방법, 결과, 주요 메트릭을 설명합니다.
k6 설치
k6는 다양한 플랫폼에서 사용할 수 있으며, 설치 방법도 간단합니다.
os별 설치방법은 여기를 참조해주세요.
1
brew install k6
기본 사용법
k6는 JavaScript로 부하 테스트시나리오를 작성할 수 있습니다. 다양한 예제는 여기를 참조해세요.
- load_test.js
1
2
3
4
5
6
7
8
9
10
import http from 'k6/http';
import { check } from 'k6';
export default function () {
const res = http.get('https://example.com');
check(res, {
'is status 200': (r) => r.status === 200,
});
}
위와같이 파일을 작성후 아래의 명령어로 부하 테스트를 진행합니다.
1
k6 run load_test.js
json file output
output file을 json으로 하고 싶다면 아래의 명령어를 실행해 json 파일
로 결과를 export할 수 있습니다.
1
k6 run --out json=result.json load_test.js
html report output
html report로도 보고싶다면 기존 load_test.js
에 아래의 코드을 추가합니다.
1
2
3
4
5
6
7
8
9
10
import { htmlReport } from "https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js";
...기존 부하테스트 코드...
// 맨 아래에 추가
export function handleSummary(data) {
return {
"summary.html": htmlReport(data),
};
}
html report와 json 파일을 모두 export 하고 싶다면??
위의 htmlReport를 import하고 output file 옵션을 json으로 주면 된다!
1 k6 run --out json=result.json load_test.js
web dashboard
환경변수를 사용하여 대시보드로 부하테스트 결과를 볼 수 있습니다.
1
K6_WEB_DASHBOARD=true k6 run load_test.js
overview
vu, 요청 비율, fail 횟수 등을 간략하게 보여줍니다.
timings
http 관련 그래프를 보여줍니다.
summary
metric 집계를 보여줍니다.
report
overview, timings, summary 의 결과를 report로 보여줍니다.
k6 수집 Metrics
k6에서 확인할 수 있는 metric은 다음과 같습니다.
1. HTTP 요청 관련 메트릭
메트릭 | 설명 |
---|---|
http_reqs | 실행된 HTTP 요청 수 |
http_req_duration | HTTP 요청이 완료되기까지 걸린 시간 (ms) |
http_req_waiting | 서버가 응답하기까지의 시간 (TTFB, Time To First Byte) |
http_req_connecting | TCP 연결에 소요된 시간 |
http_req_tls_handshaking | TLS 핸드셰이크에 걸린 시간 |
http_req_sending | 요청을 보내는 데 걸린 시간 |
http_req_receiving | 응답을 받는 데 걸린 시간 |
http_req_failed | 실패한 HTTP 요청의 비율 |
2. 네트워크 및 시스템 성능 메트릭
메트릭 | 설명 |
---|---|
vus | 현재 활성 사용자 수 (Virtual Users) |
vus_max | 테스트 중 최대 활성 사용자 수 |
iterations | 시뮬레이션된 요청 수 (각 VU가 실행한 루프 횟수) |
data_sent | 전송된 총 데이터 크기 (bytes) |
data_received | 수신된 총 데이터 크기 (bytes) |
3. 응답 코드 관련 메트릭
메트릭 | 설명 |
---|---|
http_req_duration{status:200} | HTTP 200 응답을 받은 요청의 평균 응답 시간 |
http_req_duration{status:500} | HTTP 500 응답을 받은 요청의 평균 응답 시간 |
checks | K6의 check 함수에서 통과한 비율 |
4. 기타 성능 지표
메트릭 | 설명 |
---|---|
group_duration | 특정 그룹 블록의 실행 시간 |
iteration_duration | 각 VU가 전체 시나리오를 완료하는 데 걸린 시간 |
thresholds | 설정한 임계값(Threshold) 조건을 충족했는지 여부 |
5. 응답 시간 분포 (Percentiles)
메트릭 | 설명 |
---|---|
http_req_duration{p(90)} | 전체 요청 중 90%가 해당 시간 이하로 응답을 받은 경우 |
http_req_duration{p(95)} | 전체 요청 중 95%가 해당 시간 이하로 응답을 받은 경우 |
http_req_duration{p(99)} | 전체 요청 중 99%가 해당 시간 이하로 응답을 받은 경우 |
OAS와의 통합
swagger문서와 통합한다면 작성한 API에 대해서 테스트 자동화 코드를 생성할 수 있습니다.(참조)
1. swagger 문서 준비
Spring Boot에서 springdoc-openapi 사용하여 Swagger 문서를 생성하거나, json 파일로 된 swagger 문서를 준비합니다.
2. Swagger 문서를 기반으로 K6 스크립트 생성
openapi-generator를 사용하여 K6 테스트 스크립트(.js 파일)를 자동 생성합니다.
- OpenAPI Generator CLI를 설치: npm, docker 모두 가능
1 2 3
# 둘중 하나로 사용 npm install -g @openapitools/openapi-generator-cli docker pull openapitools/openapi-generator-cli
- K6 스크립트 생성
1 2
openapi-generator-cli generate -i http://localhost:8080/v3/api-docs -g k6 -o k6-tests openapi-generator-cli generate -i swagger.json -g k6 -o k6-tests
-i
: OpenAPI 문서 경로-g
: 생성할 코드의 언어(k6 사용)-o
: 생성된 파일이 저장될 디렉토리(k6-tests)
이 명령어를 실행하면 k6-tests/ 디렉토리에 K6 테스트 스크립트(test.js 등)가 자동 생성됩니다.
K6로 부하 테스트 실행
자동 생성된 test script를 실행합니다.
1
k6 run k6-tests/test.js
결론
부하테스트는 시스템의 성능을 분석하고 최적화하는 데 필수적인 작업입니다.
여러 부하 테스트 툴들 중에서 k6는 JavaScript 기반으로 간단하게 테스트를 작성할 수 있으며, 분산 부하 테스트를 지원하고 높은 성능을 자랑합니다. 또한, 실시간으로 위에서 설명한 metric 및 테스트 결과를 json, html 혹은 dashboard를 통해서 확인할 수 있습니다.
[출처]
- https://k6.io/
- https://grafana.com/docs/k6/latest/
- https://grafana.com/docs/k6/latest/results-output/end-of-test/
- https://k6.io/blog/load-testing-your-api-with-swagger-openapi-and-k6/
- https://www.artillery.io/