도구 📍
JMeter
Apache JMeter - Apache JMeter™
Apache JMeter™ The Apache JMeter™ application is open source software, a 100% pure Java application designed to load test functional behavior and measure performance. It was originally designed for testing Web Applications but has since expanded to oth
jmeter.apache.org
Apache에서 만든 가장 널리 사용되는 부하 테스트 도구
- 특징
- GUI
- 다양한 프로토콜
- 방대한 커뮤니티
- 분산 부하 테스트 O
- Master - Slave 구조
- 자체적으로 report 가능
- 단점
- GUI 무거움
- 리소스 많이 소모 → 약 1000명 가상 사용자 이상이면 분산 실행 설정
- JMeter의 자체적인 힙 메모리 양 모니터링 필요
- XML로 스크립팅 → 협업 어려움
K6
https://grafana.com/docs/k6/latest/
Grafana k6 | Grafana k6 documentation
Grafana Cloud k6 Leverage the k6 OSS capabilities in Grafana Cloud, with built-in dashboards, insights into your application performance, and the ability to bring together teams in one place to resolve issues faster.
grafana.com
Grafana Labs에서 만든 오픈소스 부하테스트 도구
- 특징
- CLI툴
- 분산 부하 테스트 O - k6-operator
- 단일 인스턴스 동일한 리소스인 경우 수만명 가상 사용자 O (why? go기반)
- 매우 빠른 설치(의존성 X)
- JS로 작성 → 협업하기 쉬움
- 단점
- GUI X
- 제한된 프로토콜. HTTP 기반 최적화
- report UI 없음→ 데이터 분석 도구와 통합 필요 - Grafana Cloud
Vegeta
https://github.com/tsenart/vegeta
간단한 HTTP 부하 테스트 도구 (CLI로 사용)
- 특징
- CLI 툴 → 심플. 가벼움
- Go 라이브러리로 사용 가능
- report → JSON, 히스토그램(https://hdrhistogram.github.io/HdrHistogram/plotFiles.html)
- 분산 부하테스트 가능
- built-in Prometheus Exporter 가지고 있음; 모니터링 가능
- 단점
- HTTP 부하 테스트만 가능
- 고급 시나리오 작성 어려움 - 초당 요청 비율(rate) 와 공격 지속 시간(duration) 기반 트래픽 생성
- 정확도가 좀 떨어지는 느낌
Speedscale
Getting Started | Speedscale Docs
You've got to start somewhere. Why not here?
docs.speedscale.com
- 특징
- production의 트래픽 사용 가능 - 사이드카 방식으로 API 계측 후 저장. → 테스트의 기반
- Kubernetes와 통합 → CLI 제공 (EKS 가능) speedctl
- GUI
- 단점
- 작은 커뮤니티
Locust
https://docs.locust.io/en/stable/index.html
HTTP 및 기타 프로토콜을 위한 오픈 소스 성능/부하 테스트 도구
- 특징
- Python 코드로 테스트 정의
- 분산 부하 테스트 가능
- 웹 기반 UI - 이곳에서 VU, Run time 설정 가능
- 단점
도구 테스트 📍
JMeter
https://creampuffy.tistory.com/209
K6
https://grafana.com/docs/k6/latest/get-started/
https://grafana.com/blog/2022/06/23/running-distributed-load-tests-on-kubernetes/
https://sjparkk-dev1og.tistory.com/221
- 스크립트
import http from 'k6/http';
import { sleep, check } from 'k6';
export const options = {
vus: 10,
duration: '30s',
};
export default function() {
let res = http.get('http://localhost:3000');
check(res, { "status is 200": (res) => res.status === 200 });
sleep(1);
}
k6 run k6-test.js
- 결과
/\ Grafana /‾‾/
/\ / \ |\ __ / /
/ \/ \ | |/ / / ‾‾\
/ \ | ( | (‾) |
/ __________ \ |_|\_\ \_____/
execution: local
script: k6-stress-test.js
output: -
scenarios: (100.00%) 1 scenario, 10 max VUs, 1m0s max duration (incl. graceful stop):
* default: 10 looping VUs for 30s (gracefulStop: 30s)
✓ status is 200
checks.........................: 100.00% 300 out of 300
data_received..................: 71 kB 2.4 kB/s
data_sent......................: 24 kB 797 B/s
http_req_blocked...............: avg=48.29µs min=1µs med=6µs max=1.25ms p(90)=13µs p(95)=17.04µs
http_req_connecting............: avg=7.7µs min=0s med=0s max=283µs p(90)=0s p(95)=0s
http_req_duration..............: avg=2.61ms min=206µs med=2.47ms max=7.72ms p(90)=4.57ms p(95)=5.4ms
{ expected_response:true }...: avg=2.61ms min=206µs med=2.47ms max=7.72ms p(90)=4.57ms p(95)=5.4ms
http_req_failed................: 0.00% 0 out of 300
http_req_receiving.............: avg=53.18µs min=6µs med=40µs max=1.33ms p(90)=94µs p(95)=107.09µs
http_req_sending...............: avg=28.9µs min=3µs med=17µs max=1.15ms p(90)=42µs p(95)=63.04µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=2.53ms min=186µs med=2.36ms max=7.56ms p(90)=4.49ms p(95)=5.32ms
http_reqs......................: 300 9.967463/s
iteration_duration.............: avg=1s min=1s med=1s max=1.01s p(90)=1s p(95)=1s
iterations.....................: 300 9.967463/s
vus............................: 10 min=10 max=10
vus_max........................: 10 min=10 max=10
running (0m30.1s), 00/10 VUs, 300 complete and 0 interrupted iterations
default ✓ [======================================] 10 VUs 30s
Locust
https://docs.locust.io/en/stable/writing-a-locustfile.html#writing-a-locustfile
사전에 가상환경 activate
- 스크립트
from locust import HttpUser, TaskSet, task, between
class UserBehavior(TaskSet):
@task
def index(self):
self.client.get("/")
class WebsiteUser(HttpUser):
tasks = [UserBehavior]
wait_time=between(1,3)
- 결과
http://localhost:8089
Vegeta
- 스크립트
echo "GET http://localhost:3000" | vegeta attack -duration=10s | vegeta report
- 결과
Requests [total, rate, throughput] 500, 50.10, 50.09
Duration [total, attack, wait] 9.981s, 9.98s, 1.167ms
Latencies [min, mean, 50, 90, 95, 99, max] 225.333µs, 977.122µs, 1.023ms, 1.396ms, 1.531ms, 2.001ms, 4.392ms
Bytes In [total, mean] 5500, 11.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:500
Error Set:
비용 정리 📍
https://speedscale.com/pricing/
https://www.locust.cloud/pricing
- JMeter → 무료
- K6 → 로컬 테스트는 무료 / K6 Cloud는 유료(report UI 존재)
- Vegeta → 무료
- SpeedScale → 로컬 테스트인 proxymock은 무료 / 나머지 유료
- Locust → 로컬 테스트 무료 / Locust Cloud 유료 (detailed analytics)
'Testing' 카테고리의 다른 글
[테스트] 테스트란? (0) | 2025.03.03 |
---|