Skip to content

✍️ 필사 모드: 로드/성능 테스트 도구 2026 — k6·Locust·Vegeta·Gatling·Artillery·JMeter 심층 비교 (JMeter 너머의 풍경)

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

프롤로그 — "초당 만 건 가능합니다"라는 거짓말

2026년 어느 회사의 출시 전날.

PM: "초당 만 건 가능하죠?" 백엔드: "JMeter로 돌려봤습니다. 통과했어요." SRE: "어떤 시나리오로?" 백엔드: "constant 만 RPS로 5분..." SRE: "production traffic 패턴은요? warm-up이 들어갔어요? p99는?" 백엔드: "..."

이 장면이 2026년에도 흔하다. 도구는 좋아졌는데 측정 문화는 그대로다. "통과했다"라고 말하지만, 무엇이 통과했는지, 어떤 분포에서 통과했는지, production과 얼마나 닮았는지는 답이 없다. 그러는 사이 출시 후 실제 트래픽은 burst로 들어오고, 캐시가 콜드 상태에서 시작하고, p99는 SLO를 깨고, 그 모든 게 "통과한" 테스트와 무관하게 일어난다.

도구 자체는 좋아졌다. 2010년대의 JMeter 중심 세계는 이제 k6(Grafana) 가 사실상 표준이 된 풍경으로 바뀌었고, Locust·Vegeta·Gatling·Artillery·Bombardier 같은 선택지가 각자의 영역에서 자리를 잡았다. 마이크로 벤치마크 영역에는 wrk·wrk2·autocannon이 살아 있고, gRPC·WebSocket 같은 비-HTTP 프로토콜에는 ghz·fortio가 따로 있다.

이 글은 2026년의 로드/성능 테스트 도구 지도를 그린다. 각 도구의 위치, 같은 시나리오를 도구별로 어떻게 짜는지, "좋은 로드 테스트"란 무엇인지, 그리고 우리 팀이 어떻게 고를지까지.


1장 · 로드 테스트의 4가지 목적 — 무엇을 잴 건지부터

도구를 고르기 전에 목적부터 정리한다. 같은 도구가 모든 목적에 맞지 않는다.

  1. 마이크로 벤치마크 (micro-benchmark) — 단일 엔드포인트의 한계 throughput과 p99 latency를 잰다. "이 핫 패스가 얼마나 빠른가?" 작은 변경의 회귀를 잡는 용도. wrk, autocannon, Bombardier, Vegeta.
  2. 부하 테스트 (load test) — 예상 트래픽 수준에서 시스템이 SLO 안에서 동작하는가. 보통 일정 RPS를 일정 시간 유지. k6, Locust, Gatling, Artillery, JMeter.
  3. 스트레스 테스트 (stress test) — 한계를 찾는다. 어느 지점에서 시스템이 무너지는가, 어떻게 무너지는가, 회복 가능한가. 위 도구들 + 시나리오 설계.
  4. 스파이크/소크 테스트 (spike & soak) — 갑작스러운 트래픽 폭증(스파이크)과 장시간 유지(소크, 메모리 누수·연결 누수 잡기). k6, Locust가 시나리오 표현에 강하다.

추가로 카오스 테스트(장애 주입 + 부하)는 별도의 축이지만, 부하 도구로 트래픽을 흘리며 chaos tool로 장애를 주입하는 조합이 흔하다.

핵심: "성능 테스트"라는 단일 단어가 위의 4가지를 모두 가리킨다. 도구를 고를 때는 "어떤 종류의 테스트를 주로 할 것인가"부터 답해야 한다. 마이크로 벤치마크에 JMeter를 끄집어내는 건 과하고, 복잡한 시나리오에 wrk를 쓰는 건 부족하다.


2장 · 도구 지도 2026 — 한눈에

도구언어/스크립트강점약점대표 사용처
k6JS (ES2015+), Go 런타임모던 기본값, 풍부한 출력, 클라우드 옵션, gRPC/WS/브라우저분산은 OSS에서 직접 구성2026년의 일반 기본값
LocustPython분산이 쉽다, Python 코드 가능단일 워커 throughput 한계Python 팀, 행위 모델 복잡
VegetaGo (CLI + 라이브러리)한 줄로 실행, 결과 분석 강력시나리오 표현은 단순HTTP 마이크로 벤치, 빠른 측정
GatlingScala/Java DSL시나리오 표현력, 엔터프라이즈 리포팅Scala 학습 곡선대규모, JVM 친화 조직
ArtilleryNode.js, YAML빠른 시작, YAML로 표현고부하에서 단일 노드 한계Node 팀, CI 시나리오
wrk / wrk2C, Lua 스크립트매우 가볍고 빠른 HTTP 벤치HTTP만, 시나리오 단순핫 패스 마이크로 벤치
autocannonNode.jsnpm 설치만으로 즉시Node 팀 외에는 동기 약함Node API 빠른 벤치
BombardierGo정말 단순하고 빠른 CLI시나리오 거의 없음한 줄 부하 측정
JMeterJava, GUI/XML오래된 자료·플러그인 생태계XML 시나리오, 모던 UX 아님엔터프라이즈, 기존 자산
ghzGo, CLIgRPC 전용, 단순gRPC 외에는 부적합gRPC 서비스 벤치
fortioGo (Istio)gRPC + HTTP, 분포 분석UI 평이서비스 메시 검증

한 줄 정리: 2026년의 "처음 잡는 도구"는 대체로 k6다. 팀이 Python 친화적이면 Locust. 한 줄 마이크로 벤치는 Vegeta(또는 wrk). 엔터프라이즈/JVM 친화 조직과 기존 자산은 JMeter/Gatling. Node 친화 팀의 빠른 CI 시나리오는 Artillery. gRPC는 ghz 또는 k6 gRPC 모듈.


3장 · k6 — 2026년의 일반 기본값

현재 상태 (2026년 5월): Grafana Labs 산하. k6 OSS 바이너리는 무료, Grafana Cloud k6에서 분산 실행/대시보드를 유료로 제공. v0.5x 대 안정 릴리스가 꾸준히 나오고 있으며, browser 모듈(Playwright 백엔드)·gRPC·WebSocket·xk6 확장 생태계가 확장 중이다.

왜 기본값이 됐나:

  • JS로 시나리오 작성 — 엔지니어 다수가 읽고 짤 수 있다.
  • Go 기반 단일 바이너리 — 설치가 쉽다. CPU 효율도 좋다 (Locust보다 단일 워커 throughput이 훨씬 높다).
  • 출력이 풍부 — 콘솔에서 p50/p90/p95/p99까지 기본으로 본다. Prometheus·InfluxDB·Datadog로 export 가능.
  • scenario·executor 모델constant-vus, ramping-arrival-rate, per-vu-iterations 등 표현력이 좋다.
  • 확장 가능 — xk6로 SQL·Kafka·Redis 모듈을 붙일 수 있다.

기본 스크립트 (4장에서 비교용으로 다시 본다):

// k6 script: login + ramp 50 → 200 RPS for 5min
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  scenarios: {
    login_ramp: {
      executor: 'ramping-arrival-rate',
      startRate: 50,
      timeUnit: '1s',
      preAllocatedVUs: 50,
      maxVUs: 500,
      stages: [
        { target: 50, duration: '1m' },
        { target: 200, duration: '5m' },
        { target: 200, duration: '2m' },
      ],
    },
  },
  thresholds: {
    http_req_duration: ['p(99)<500'],
    http_req_failed: ['rate<0.01'],
  },
};

export default function () {
  const res = http.post('https://api.example.com/login', JSON.stringify({
    user: 'demo',
    pass: 'pw'
  }), { headers: { 'Content-Type': 'application/json' } });
  check(res, { 'status 200': (r) => r.status === 200 });
  sleep(1);
}

k6 Cloud(Grafana Cloud k6) 비용 감각 (2026년 기준): 무료 플랜은 월 50 VUh, Pro 플랜은 $299/월 부터 시작하며 VUh와 동시 실행 한도가 늘어난다. 분산 실행/지역 분산이 필요하면 cloud 옵션이 편하고, 대안은 self-host 분산(여러 노드에서 같은 스크립트 실행, 결과 집계).

한계:

  • 분산 실행이 OSS에서는 직접 구성해야 한다 — k8s operator(grafana/k6-operator)가 있지만 운영 부담.
  • JS 런타임은 V8이 아니라 Goja(Go에서 임베드된 ES5+). 일부 모던 JS feature는 babel transform 필요.
  • 데이터 변환 무거운 로직은 시나리오 외부에서 처리하는 게 안전.

4장 · 같은 시나리오, 도구별 비교 — POST /login + ramp 50 → 200 RPS

같은 시나리오를 k6 / Locust / Vegeta로 어떻게 표현하는지 나란히 본다.

k6

위 3장의 스크립트 그대로. 핵심은 ramping-arrival-rate executor와 thresholds로 p99·실패율을 코드로 선언.

Locust (Python)

# locustfile.py
from locust import HttpUser, task, LoadTestShape, constant_throughput

class LoginUser(HttpUser):
    wait_time = constant_throughput(1)  # 1 req/sec per user

    @task
    def login(self):
        self.client.post(
            "/login",
            json={"user": "demo", "pass": "pw"},
            headers={"Content-Type": "application/json"},
        )

class RampShape(LoadTestShape):
    stages = [
        {"duration": 60, "users": 50, "spawn_rate": 50},
        {"duration": 360, "users": 200, "spawn_rate": 5},
        {"duration": 480, "users": 200, "spawn_rate": 0},
    ]

    def tick(self):
        run_time = self.get_run_time()
        for stage in self.stages:
            if run_time < stage["duration"]:
                return (stage["users"], stage["spawn_rate"])
        return None

실행: locust -f locustfile.py --headless -H https://api.example.com. 분산 모드는 master/worker(--master, --worker)로 쉽게 분리되며, k8s helm chart도 잘 알려져 있다.

Vegeta (CLI)

# targets.txt
# POST https://api.example.com/login
# Content-Type: application/json
# @body.json

# step 1: 50 RPS for 1m
echo "POST https://api.example.com/login" | \
  vegeta attack -rate=50 -duration=60s -body=body.json \
                -header="Content-Type: application/json" \
  | vegeta report -type=hist[0,100ms,200ms,500ms,1s]

# step 2: 200 RPS for 5m
echo "POST https://api.example.com/login" | \
  vegeta attack -rate=200 -duration=5m -body=body.json \
                -header="Content-Type: application/json" \
  | tee result.bin \
  | vegeta report
vegeta plot result.bin > plot.html

Vegeta는 시나리오 자체가 단순하다 — 일정 rate를 일정 시간 동안 친다. ramp는 보통 단계별 명령을 이어 실행하거나, 셸 스크립트로 외부에서 만든다. 그 단순함이 강점이다 — 한 줄로 측정이 끝나고, vegeta report -type=json이나 vegeta plot으로 분포·시계열을 본다.

비교 관찰:

  • 표현력: Locust(가장 자유) ≈ k6 > Vegeta. Vegeta는 일부러 단순하다.
  • CPU 효율: k6 > Vegeta > Locust (단일 워커 기준; Locust는 분산으로 보완).
  • CI 친화: k6(threshold로 exit code) ≈ Vegeta(report로 grep). Locust도 headless로 CI 가능.
  • 결과 시각화: k6(Grafana Cloud k6 또는 직접 Prometheus) > Locust(웹 UI) > Vegeta(plot HTML).

5장 · Locust — Python 팀의 편안한 친구

현재 상태 (2026년): 활발히 유지보수 중. v2.x 안정. Locust는 "코드로 표현 가능한 행위 모델"이 강점이다. 사용자가 무엇을 하는지 클래스/메서드로 표현하고, @task 데코레이터로 가중치를 준다.

언제 적합한가:

  • 팀이 Python 친화적이고 데이터/추상화 라이브러리를 그대로 부르고 싶을 때.
  • 사용자 행위 모델이 복잡할 때(여러 페이지를 순회, 상태 보유).
  • 분산 실행이 필요하지만 별도 SaaS는 쓰기 싫을 때 — --master/--worker로 매우 단순.

한계:

  • 단일 워커의 throughput은 k6보다 낮다. Python의 gevent 기반 동시성은 효율적이지만 Go보다는 무겁다.
  • 결과 시각화는 내장 웹 UI가 있지만 k6/Grafana 조합만큼 풍부하지 않다.

: Locust의 강점은 분산이 쉽다는 것이다. 100k+ RPS가 필요하면 워커 수십 개를 띄우는 게 자연스럽다. k8s에 helm chart로 띄우고, Prometheus로 메트릭 모으는 패턴이 익숙해지면 운영이 단순해진다.


6장 · Vegeta — 한 줄의 우아함

현재 상태 (2026년): 단일 메인테이너 중심으로 유지보수 중. 안정적이고 단순하다. 신기능은 거의 없지만, 그게 미덕이다.

왜 Vegeta가 살아남았나:

  • 한 줄로 측정echo "GET https://..." | vegeta attack -rate=100 -duration=30s | vegeta report. 다른 도구라면 파일 만들고, runner 띄우고, 컨테이너 마운트하는 게 vegeta는 한 줄이다.
  • 분포 분석이 정확vegeta report 출력에 p50/p90/p95/p99/min/mean/max가 한 번에 나온다. histogram 버킷도 CLI로 지정.
  • 결과 직렬화.bin 형식으로 저장 후 나중에 reproc 가능. CI에서 bin을 artifact로 저장하고 나중에 분석.

한계:

  • 시나리오 표현이 단순하다 — 일정 rate 또는 step 묶음. 복잡한 사용자 시뮬레이션엔 부적합.
  • 분산 모드는 CLI 도구다 보니 직접 구성. 보통 여러 머신에서 같은 명령을 실행하고 bin을 모아 합치는 방식.

대표 사용: 핫 패스 하나의 latency 분포를 정확히 측정하고 싶을 때, CI에서 회귀를 잡는 마이크로 벤치, "지금 서버가 살아 있나" 빠른 체크.


7장 · Gatling — JVM 진영의 강자

현재 상태 (2026년): Gatling 3.x 안정. Gatling Enterprise(유료, 구 FrontLine)와 OSS 둘 다 활발. Scala DSL이 기본이지만 Java/Kotlin DSL도 정식 지원한다.

왜 여전히 쓰이나:

  • DSL의 표현력 — 시나리오·체이닝·assertion이 코드처럼 자연스럽다.
  • 리포팅 — HTML 리포트가 매우 깔끔하다. enterprise는 분산/팀 협업.
  • JVM 친화 조직 — Maven/Gradle 빌드에 자연스럽게 들어간다.
  • Scala 학습 비용은 줄었다 — Java DSL이 1급 시민이 됐다.

언제 적합한가:

  • JVM 기반 백엔드를 가진 조직, 빌드 시스템에 통합하고 싶을 때.
  • 시나리오가 복잡하고 코드 리뷰 가능한 형태로 두고 싶을 때.
  • 엔터프라이즈 지원이 필요한 환경.

한계:

  • 가벼운 한 줄 측정은 부적합 — JVM 기동·SBT/Maven 비용.
  • Scala 진입 장벽은 줄었지만 0은 아니다.

8장 · Artillery — YAML 시나리오의 간편함

현재 상태 (2026년): OSS + Cloud(유료). YAML로 시나리오를 표현하는 게 매력. 최근 v2 부터는 분산 실행(Cloud) 옵션도 강화됐다.

왜 쓰이나:

  • YAML 시나리오 — 코드 작성 없이 "URL·페이로드·플로우"를 선언적으로.
  • Node.js 기반 — Node 팀에 친숙.
  • 빠른 시작npm install -g artillery 후 yml 파일 하나면 실행.

한계:

  • 단일 노드 throughput은 k6보다 낮다 (Node 이벤트 루프 한계).
  • 매우 큰 부하에선 Cloud 또는 다중 인스턴스가 필요.

예시 시나리오 (조금 다른 형태로):

config:
  target: 'https://api.example.com'
  phases:
    - duration: 60
      arrivalRate: 50
    - duration: 300
      arrivalRate: 50
      rampTo: 200
    - duration: 120
      arrivalRate: 200
scenarios:
  - flow:
      - post:
          url: '/login'
          json:
            user: 'demo'
            pass: 'pw'
          expect:
            - statusCode: 200

9장 · JMeter — 살아 있는 노장

현재 상태 (2026년): Apache JMeter 5.x 유지보수 중. 학습 자료가 가장 많고, 플러그인 생태계가 가장 넓다. GUI 중심이지만 헤드리스 실행도 정식 지원.

왜 여전히 보이나:

  • 기존 자산 — 수많은 조직이 .jmx 파일을 갖고 있다. 마이그레이션 비용 vs. 유지 비용.
  • 플러그인 — Prometheus listener, custom protocol, blazemeter 통합 등.
  • 금융·통신 등 엔터프라이즈 — 사내 표준이 JMeter인 경우.
  • GUI 친화 — 코드를 모르는 QA가 쓰기 좋다 (장단 양면).

왜 새로 시작하는 팀은 거의 안 고르나:

  • XML(.jmx) 시나리오 — git diff 친화적이지 않다.
  • 모던 UX·CLI 친화가 약하다.
  • CI 통합이 가능하지만 k6/Locust에 비해 손이 더 간다.

가이드: 신규 프로젝트에서 JMeter를 새로 선택할 이유는 거의 없다. 다만 기존 자산이 있다면 그것을 폐기하고 마이그레이션하는 비용은 별도 결정. 점진적으로 새 테스트는 k6/Gatling으로 짜고, 기존은 유지하는 패턴이 흔하다.


10장 · 마이크로 벤치마크 — wrk / wrk2 / autocannon / Bombardier

이 4개 도구는 "한 엔드포인트의 한계 throughput과 latency 분포"를 빠르게 잡는 데 특화됐다.

wrk

  • C로 작성, 매우 빠르다. Lua 스크립트로 약간의 커스터마이즈.
  • HTTP만, keep-alive 친화.
  • 단점: rate-limit이 없다 — 한계 throughput을 측정하므로 항상 max 부하.

wrk2

  • wrk의 fork. 고정 rate를 지원 — "정확히 1000 RPS를 30초 동안" 같은 측정 가능.
  • 마이크로 벤치 + 고정 rate 측정에 이상적.
  • coordinated omission 보정에 강점.

autocannon

  • Node.js 기반. npm install -g autocannonautocannon -c 50 -d 30 https://....
  • Node 친화 팀의 빠른 CI 벤치에 적합.

Bombardier

  • Go 단일 바이너리. 매우 단순하고 빠르다. bombardier -c 125 -n 1000000 https://....
  • 시나리오 표현 거의 없지만, 그게 핵심.
  • 메인테이너 활동은 있지만 신기능보다는 안정 유지 모드.

언제 무엇을:

  • 정확한 latency 분포와 고정 rate가 필요 → wrk2.
  • 그냥 빠르게 한 번 부하 → wrk 또는 Bombardier.
  • Node 팀이고 CI 통합 → autocannon.
  • 시나리오가 조금이라도 필요 → 이 4개가 아니라 Vegeta 또는 k6.

11장 · 비-HTTP 프로토콜 — gRPC, WebSocket, 브라우저

2026년의 부하 측정은 HTTP만이 아니다. gRPC·WebSocket·실 브라우저(Headless Chrome) 모두 측정 대상이다.

gRPC

  • ghz — gRPC 전용 CLI 도구. ghz --insecure --proto ./svc.proto --call svc.Hello -c 50 -n 10000 .... 단순하고 정확.
  • k6 gRPC 모듈import grpc from 'k6/net/grpc'. 시나리오 안에 gRPC 호출을 섞을 수 있다.
  • fortio — Istio 출신. HTTP + gRPC 둘 다, p50–p999 분포 분석에 강하다.

WebSocket

  • k6 WS 모듈import ws from 'k6/ws'. 연결 수·메시지 RPS·세션 길이 시나리오 가능.
  • Artillery — WS를 기본 지원, YAML로 시나리오.
  • Gatling — WS 시나리오 표현력이 좋음.

브라우저 (Real Browser Load)

  • k6 browser 모듈 — Playwright 백엔드. 실제 브라우저로 JS 실행·렌더·페이지 상호작용을 측정. 사용 사례: 프런트엔드 회귀, 페이지 로드 SLO.
  • 비용 주의: 브라우저 인스턴스는 무거우므로 RPS가 아니라 동시 세션 수로 사고.

12장 · "좋은 로드 테스트"란 무엇인가 — 2026 체크리스트

도구가 좋아도 시나리오가 나쁘면 결과도 나쁘다. 좋은 로드 테스트의 핵심.

1) production-like 데이터

  • 사용자 ID, 페이로드 크기, 토큰 분포가 production과 닮아야 한다.
  • "한 사용자가 같은 페이지를 1만 번"은 캐시에 다 맞는다 — production은 그렇지 않다.
  • production에서 sampling한 페이로드를 anonymize해서 사용하는 패턴.

2) 일정 rate가 아니라 분포

  • "constant 1000 RPS"는 measurement용이지 reality와 멀다.
  • production은 burst·dip·diurnal 패턴이 있다.
  • k6의 ramping-arrival-rate, Locust의 LoadTestShape로 시나리오를 모델링.

3) warm-up과 ramp-up

  • 캐시·DB connection pool·JIT가 콜드 상태로 시작하는 측정은 항상 비관적이다.
  • 처음 1–2분은 warm-up으로 두고 측정 구간에서 제외.

4) p99 (avg 아님)

  • "평균 latency"는 SLO의 친구가 아니다. 평균은 long-tail을 숨긴다.
  • p95·p99·p999 (특히 p99)가 SLO와 직결된다. 모든 도구의 출력에서 percentile을 확인.
  • 측정 도구가 coordinated omission으로 p99를 낮게 보고할 수 있다 — wrk2가 이 문제를 처음 잘 다뤘다.

5) error rate 분리

  • 성공 응답만으로 latency를 잡으면 죽은 요청을 못 본다.
  • 4xx·5xx·timeout·connection refused를 따로 카운트하고, 임계치를 설정.

6) 다중 측정점

  • 부하 도구의 클라이언트 측 latency뿐 아니라 서버 측 RED(Rate·Error·Duration) 메트릭, downstream 의존성도 함께 본다.
  • 부하 도구가 "느림"을 보고하는데 서버 메트릭은 빠르다 → 네트워크/측정 문제. 그 반대도 있다.

7) 한 번 말고 정기적

  • 출시 전 한 번이 아니라, 주간·월간 회귀 테스트로 둔다.
  • 코드 변경이 latency 분포에 미친 영향을 시계열로.

13장 · self-host 대 cloud — 비용과 운영

분산 실행이 필요해지면 두 갈래다.

Self-host 분산

  • k6 OSS + grafana/k6-operator (k8s) — pod로 실행, 결과를 Prometheus/InfluxDB로.
  • Locust master/worker — 가장 단순. helm chart로 워커 N개 띄움.
  • 여러 노드에서 같은 명령 + 결과 머지 — vegeta·wrk·Bombardier 식 접근.

장점: 비용 통제, 데이터가 인하우스. 단점: 운영 부담, 지역 분산 어려움.

Cloud

  • Grafana Cloud k6 — 분산 실행, 지역, 대시보드. 월 $299 부터.
  • BlazeMeter — JMeter/Gatling/k6 호환, 엔터프라이즈 SaaS.
  • Artillery Cloud — Artillery 기반 SaaS.
  • Loader.io, k6 Cloud — 작은 부하 측정용 무료 티어부터.

장점: 지역 분산·즉시 실행·대시보드 즉시. 단점: 비용(주 1회 큰 테스트면 빠르게 $수백~수천/월).

경험칙: 단발성 대형 측정(출시 전)은 cloud가 싸고 빠르다. 정기 회귀 테스트는 self-host가 장기적으로 싸다. 둘을 섞는 조직이 많다 — 일상 CI는 self-host, 분기별 대규모는 cloud.


14장 · 도구를 고르는 결정 프레임 — 정직한 가이드

상황추천
처음 시작, 일반 백엔드k6
Python 팀, 행위 모델 복잡Locust
한 줄 마이크로 벤치Vegeta 또는 wrk2
Node 팀, CI 빠르게Artillery 또는 autocannon
엔터프라이즈 JVM 조직Gatling
기존 자산이 JMeterJMeter 유지 + k6 신규 병행
gRPC 측정ghz 또는 k6 gRPC
브라우저 부하k6 browser
단순 throughput 한계 측정wrk 또는 Bombardier
카오스 테스트 + 부하k6/Locust + Toxiproxy/Litmus

섞기는 흔하다. 한 조직 안에서 마이크로 벤치는 Vegeta, 일반 부하는 k6, 기존 큰 시나리오는 JMeter — 이런 조합이 현실의 모습. 도구를 통일하려고 무리하지 말고, 영역별로 적합한 도구를 인정하는 게 운영을 단순하게 한다.


15장 · 안티패턴과 함정

  • production에서 직접 부하 테스트 — staging 또는 격리된 production-like 환경에서 한다. production canary는 별개 기법.
  • DNS·CDN을 통과하지 않고 origin에 직접 — 측정은 통과하지만 SLO는 CDN 포함이다. 측정 경로가 user path와 같아야 한다.
  • localhost에서 측정 후 결론 — 네트워크 latency가 0이라 RPS만 보면 거짓 안전감.
  • constant rate 한 번으로 통과 선언 — production은 분포다.
  • 평균 latency만 본다 — p99를 봐야 한다.
  • 부하 도구만 본다 — 서버 메트릭과 함께 본다.
  • 출시 전 한 번 — 회귀 테스트로 둬야 한다.
  • wrk로 시나리오 측정 — 시나리오는 wrk의 일이 아니다.
  • 분산 안 짜고 단일 노드로 100k RPS 시도 — 도구의 한계를 시스템 한계로 오인.

에필로그 — 측정은 결정의 도구다

도구는 풍부하다. JMeter가 표준이던 시절은 갔고, k6가 사실상 기본값이 됐다. Locust는 Python 친화 조직의 좋은 친구, Vegeta는 한 줄 측정의 우아함, Gatling은 JVM 진영의 강자, Artillery는 빠른 시작, wrk/wrk2/autocannon/Bombardier는 마이크로 벤치의 단순함.

그러나 도구가 결과를 만들지는 않는다. 시나리오가 production을 닮았는가, percentile을 보았는가, warm-up을 두었는가, 회귀로 두었는가가 결과를 만든다. 도구를 고른 후의 일이 더 길고 중요하다.

이 글의 한 문장 요약: "잘 돌아요"는 측정이 아니다. p99·분포·시나리오로 답해야 측정이다. 도구는 그 답을 가능하게 하는 수단일 뿐, 답 자체는 우리가 정의해야 한다.

12개 항목 체크리스트

  1. 목적이 명확한가 (마이크로/부하/스트레스/스파이크 중)?
  2. production-like 데이터를 쓰는가?
  3. constant rate 말고 분포·ramp를 모델링했는가?
  4. warm-up 구간을 측정에서 제외했는가?
  5. p99(또는 p999)를 SLO에 연결했는가?
  6. error rate를 latency와 분리해서 보았는가?
  7. 클라이언트 측 + 서버 측 메트릭을 같이 보았는가?
  8. CI에 회귀로 들어가 있는가?
  9. 분산이 필요할 때 self-host/cloud 결정을 내렸는가?
  10. 비-HTTP 프로토콜이 있다면 그 도구를 함께 쓰는가 (gRPC/WS/브라우저)?
  11. 측정 경로가 user path와 일치하는가 (DNS·CDN 포함)?
  12. coordinated omission 보정을 이해하고 있는가?

안티패턴 10가지

  1. 평균 latency만 본다 — p99를 보라.
  2. constant rate 한 번으로 통과 선언 — 분포를 모델링.
  3. localhost에서 측정 후 결론 — 네트워크가 없다.
  4. production에서 직접 부하 — staging에서.
  5. 부하 도구만 본다 — 서버 메트릭과 함께.
  6. 출시 전 한 번 — 정기 회귀로.
  7. JMeter로 모든 걸 한다 — 영역별로 도구를.
  8. 분산 안 짜고 단일 노드로 무리 — 도구 한계 ≠ 시스템 한계.
  9. warm-up 무시 — 초반 데이터가 결론을 왜곡.
  10. error rate 누락 — 죽은 요청을 못 본다.

다음 글 예고

다음 글 후보: production에서 신호와 노이즈 — RED·USE·SLO 대시보드 설계, chaos engineering 2026 — Litmus·Chaos Mesh·Gremlin·AWS FIS 비교, performance regression CI — 한 줄에서 분포까지.

"측정 가능한 것이 개선 가능한 것이다. 그리고 분포를 보지 않으면 측정이 아니다."

— 로드/성능 테스트 도구 2026, 끝.


참고 / References

현재 단락 (1/313)

2026년 어느 회사의 출시 전날.

작성 글자: 0원문 글자: 14,194작성 단락: 0/313