본문으로 건너뛰기
QA-Lab
중급25

k6로 부하 테스트 만들고 결과 해석하기

k6로 실제 부하 테스트 스크립트를 작성하고, 응답 시간·에러율 같은 결과 지표를 읽어 "이 시스템이 정말 괜찮은지" 판단하는 법을 익힌다.

  • #k6
  • #부하테스트
  • #성능지표

개념

k6란

k6는 코드로 부하 테스트 시나리오를 작성하는 오픈소스 도구다. 모듈 12(레슨 3)에서 배운 코드 기반 API 테스트와 구조가 비슷하지만, 한 번의 요청이 아니라 수백~수천 개의 가상 사용자(Virtual User)가 동시에 요청을 보내는 상황을 시뮬레이션한다는 점이 다르다.

기본 스크립트 구조

import http from "k6/http"
import { check, sleep } from "k6"
 
export const options = {
  vus: 100,        // 가상 사용자 100명
  duration: "30s",  // 30초 동안 실행
}
 
export default function () {
  const res = http.get("https://api.example.com/products")
  check(res, {
    "상태 코드는 200이다": (r) => r.status === 200,
    "응답 시간이 500ms 이내다": (r) => r.timings.duration < 500,
  })
  sleep(1)
}

vus(가상 사용자 수)와 duration(지속 시간)을 조정하면, 레슨 2에서 배운 부하·스트레스·스파이크 테스트를 각각 만들 수 있다.

// 스트레스 테스트 — 부하를 점점 늘려가며 한계 지점을 찾음
export const options = {
  stages: [
    { duration: "1m", target: 100 },   // 1분 동안 100명까지 증가
    { duration: "1m", target: 500 },   // 1분 동안 500명까지 증가
    { duration: "1m", target: 1000 },  // 1분 동안 1000명까지 증가
  ],
}

결과 지표 읽는 법

k6를 실행하면 다음과 같은 결과가 나온다.

http_req_duration..........: avg=245ms  min=89ms  med=210ms  max=1.2s  p(95)=480ms
http_req_failed.............: 2.3%   23 out of 1000
vus_max......................: 100
  • http_req_duration(응답 시간) — 평균만 보면 안 된다. p(95)(95번째 백분위수, 즉 요청의 95%가 이 시간 안에 끝났다는 뜻)가 실제 사용자 체감에 더 가깝다 — 평균은 소수의 매우 빠른 응답에 가려 전체 그림을 왜곡할 수 있다
  • http_req_failed(실패율) — 요청이 에러 응답(모듈 9 레슨 2의 4xx/5xx)을 받은 비율. 이 비율이 올라가는 시점이 시스템이 부하를 못 견디기 시작하는 지점이다
  • vus_max — 이 결과가 몇 명의 동시 사용자에서 나온 것인지

평균의 함정

평균 응답 시간 245ms → "괜찮아 보인다"
p(95) 응답 시간 480ms → "실제로는 20명 중 1명이 거의 0.5초를 기다린다"

모듈 6(레슨 5)에서 배운 지표 해석의 정직함이 여기서도 중요하다 — 평균만 보고 "문제없다"고 판단하면, 실제로 많은 사용자가 겪는 느린 경험을 놓칠 수 있다.

병목 지점 찾기

부하를 늘려가며 http_req_durationhttp_req_failed를 관찰하면, 어느 지점부터 급격히 나빠지는지가 드러난다.

동시 사용자 500명: 평균 250ms, 실패율 0%
동시 사용자 1000명: 평균 260ms, 실패율 0.1%
동시 사용자 1500명: 평균 1200ms, 실패율 8% ← 여기서 급격히 나빠짐

이 "급격히 나빠지는 지점"이 바로 레슨 2에서 배운 스트레스 테스트가 찾으려는 시스템의 실질적 한계다.

실무에서 왜 필요한가

"부하 테스트 결과 평균 응답 시간 250ms로 양호합니다"라는 보고는 얼핏 안심되지만, p(95)나 실패율을 함께 보지 않으면 실제 사용자 경험을 왜곡해서 전달할 수 있다. k6로 직접 스크립트를 짜고 결과를 해석할 수 있는 QA는, 개발팀이나 인프라팀에 "정확히 어느 지점부터 문제가 시작되는지"를 근거 있는 숫자로 전달할 수 있다.

실습 과제

과제 1 — 시나리오 설계하기 (10분)

"검색 API"에 대해 부하 테스트 스크립트를 이 레슨의 예시를 참고해 설계한다(가상 사용자 수, 지속 시간, 확인할 조건 2가지를 정한다).

과제 2 — 결과 해석하기 (15분)

다음 k6 결과를 보고, 이 시스템이 500명 동시 사용자를 감당할 수 있다고 볼 수 있는지 판단하고 이유를 설명한다.

vus: 500
http_req_duration: avg=180ms  p(95)=290ms
http_req_failed: 0.05%

자가 체크리스트

  • k6 스크립트의 기본 구조(vus, duration, check)를 읽을 수 있다
  • 평균 응답 시간과 p(95)의 차이, p(95)가 왜 더 신뢰할 만한지 설명할 수 있다
  • 실패율(http_req_failed)이 무엇을 의미하는지 설명할 수 있다
  • 부하를 늘려가며 병목 지점을 찾는 방법을 설명할 수 있다

흔한 실수

  • 평균 응답 시간만 보고 성능이 괜찮다고 판단한다. p(95)·p(99) 같은 백분위수를 함께 봐야 실제 사용자 체감에 가까운 판단이 가능하다.
  • 실패율을 확인하지 않고 응답 시간만 본다. 응답이 빨라도 실패율이 높으면 실질적으로 서비스가 안 되는 것이다.
  • 한 번의 고정된 부하로만 테스트하고 병목 지점을 찾지 않는다. 점진적으로 부하를 늘려야 "어디까지 괜찮은지" 알 수 있다.

참고 자료