공부

k6 성능 테스트 실 사용 후기

반응형
k6 부하 테스트 실 사용 후기 - 완벽 가이드

k6 부하 테스트 실 사용 후기

실무 프로젝트에서 k6으로 성능 테스트하는 방법 완벽 가이드

k6란 무엇인가

k6는 개발자를 중심으로 설계된 최신 부하 테스트 도구입니다. 기존의 JMeter나 Locust와는 다르게 JavaScript 기반의 친화적인 스크립트 작성 문법을 제공하며, 실시간 메트릭 수집과 클라우드 기반 분산 테스트를 지원합니다. 2024년과 2025년을 거쳐 지속적인 업데이트를 통해 더욱 강력해지고 있습니다.

k6의 주요 특징

  • 개발자 친화적: JavaScript 기반 스크립트로 누구나 쉽게 학습할 수 있습니다. 프로그래밍 경험이 있는 개발자라면 몇 분 안에 첫 테스트를 작성할 수 있습니다.
  • 높은 성능: Go 언어로 작성되어 매우 빠른 실행 속도를 보장합니다. 한 머신에서 수천 개의 동시 연결을 처리할 수 있습니다.
  • 클라우드 통합: Grafana k6 Cloud와 연동하여 대규모 분산 테스트가 가능합니다. 전 세계 여러 리전에서 동시에 부하를 생성할 수 있습니다.
  • 유연한 시나리오: 복잡한 비즈니스 로직을 JavaScript로 자유롭게 구현할 수 있습니다. 인증, 데이터베이스 연동, 복잡한 검증 로직 등도 쉽게 추가할 수 있습니다.
  • 실시간 메트릭: 테스트 실행 중 실시간으로 성능 지표를 확인할 수 있습니다. 병목 현상을 조기에 발견하고 대응할 수 있습니다.
  • 자동화 통합: CI/CD 파이프라인에 쉽게 통합하여 지속적인 성능 테스트를 자동화할 수 있습니다.

사용 시점

k6은 다음과 같은 상황에서 특히 유용합니다:

  • 마이크로서비스 아키텍처의 API 성능 테스트
  • 배포 전 부하 테스트 자동화
  • 지속적인 성능 모니터링
  • 실시간 데이터 처리 시스템의 안정성 검증
  • 멀티테넌트 환경에서의 격리 테스트
  • 모바일 백엔드 API의 동시 연결 테스트
  • 결제 시스템이나 결제 게이트웨이의 안정성 검증
k6 설치 화면
그림 1: k6 공식 사이트와 설치 안내

설치 및 환경 설정

k6 설치는 매우 간단합니다. 공식 웹사이트에서 바이너리를 다운로드하거나 패키지 관리자를 통해 설치할 수 있습니다. 설치 후 몇 줄의 설정만으로 바로 부하 테스트를 시작할 수 있습니다.

Linux / MacOS 설치

터미널 명령어
# Homebrew를 이용한 MacOS 설치
brew install k6

# Ubuntu / Debian 설치
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 \
  --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D68
echo "deb https://dl.k6.io/deb stable main" | \
  sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6

Windows 설치

PowerShell
# Chocolatey를 이용한 설치
choco install k6

# 또는 수동으로 다운로드
# https://github.com/grafana/k6/releases에서 최신 버전 다운로드

설치 확인

버전 확인
k6 version

설치가 완료되면 버전 정보가 출력됩니다. k6을 사용할 준비가 모두 끝났습니다.

팁: Node.js와 npmk6 라이브러리를 사용하는 경우 Node.js 환경도 필요합니다. npm install k6로 npm 패키지도 설치할 수 있습니다. 이렇게 하면 IDE에서 자동 완성과 타입 체크를 지원받을 수 있습니다.
k6 설치 확인
그림 2: k6 설치 완료 후 버전 확인

첫 번째 부하 테스트 작성

이 섹션에서는 간단한 HTTP 요청 부하 테스트를 작성하는 방법을 배웁니다. 기본 구조를 이해하면 더 복잡한 시나리오도 쉽게 구현할 수 있습니다. 테스트 스크립트는 단순한 텍스트 파일이므로 아무 에디터에서나 작성할 수 있습니다.

기본 테스트 스크립트 구조

k6 스크립트는 네 가지 생명주기 함수로 구성됩니다:

  • init 컨텍스트 - 스크립트 초기화 시점에서 import와 전역 변수 선언
  • setup() - 테스트 시작 전 한 번 실행되는 초기화 함수
  • default function - 각 VU가 반복 실행하는 부분으로 가장 중요한 함수
  • teardown() - 테스트 종료 후 한 번 실행되는 정리 함수

load-test.js 전체 코드

load-test.js
import http from "k6/http";
import { check, group, sleep } from "k6";
import { Rate, Counter, Trend } from "k6/metrics";

// 커스텀 메트릭 정의
const successRate = new Rate("success_rate");
const requestCount = new Counter("request_count");
const responseTrend = new Trend("response_trend");

// 테스트 시나리오 설정
export const options = {
  stages: [
    { duration: "10s", target: 5 },   // Ramp-up: 10초간 5 VU
    { duration: "20s", target: 10 },  // Sustain: 20초간 10 VU
    { duration: "10s", target: 0 },   // Ramp-down: 10초간 0 VU
  ],
  thresholds: {
    http_req_duration: ["p(95)<2000"],
    http_req_failed: ["rate<0.1"],
    success_rate: ["rate>0.9"],
  },
};

export default function () {
  // 메인 페이지 요청
  const mainPage = http.get("https://test.k6.io/");
  check(mainPage, {
    "상태 코드 200": (r) => r.status === 200,
    "응답 시간 1초 미만": (r) => r.timings.duration < 1000,
  });
  successRate.add(mainPage.status === 200);
  requestCount.add(1);
  responseTrend.add(mainPage.timings.duration);

  sleep(1);

  // 연락처 페이지 요청
  const contacts = http.get("https://test.k6.io/contacts.php");
  check(contacts, {
    "연락처 상태 200": (r) => r.status === 200,
  });

  sleep(1);

  // 뉴스 페이지 요청
  const news = http.get("https://test.k6.io/news.php");
  check(news, {
    "뉴스 상태 200": (r) => r.status === 200,
  });

  sleep(Math.random() * 2);
}

코드 설명

import 문: k6 라이브러리에서 필요한 함수와 메트릭을 import합니다. http는 HTTP 요청 모듈, check는 검증 함수, group은 로직 그룹화, sleep은 대기 함수입니다.

커스텀 메트릭: Rate, Counter, Trend 등으로 원하는 지표를 정의합니다. successRate는 성공률을 기록하고, errorCount는 에러 발생 횟수를, responseTime은 응답 시간을 추적합니다.

options 객체: stages로 부하를 단계별로 증가시키고, thresholds로 통과 조건을 설정합니다. p(95)는 95 percentile을 의미하므로 95%의 요청이 500ms 이내에 완료되어야 합니다.

setup 함수: 테스트 실행 전에 필요한 초기화 작업을 수행합니다. 데이터베이스 연결, 테스트 사용자 생성 등을 할 수 있습니다.

default 함수: 각 VU가 반복적으로 실행하는 메인 로직입니다. 여기서 실제 HTTP 요청을 보내고 응답을 검증합니다.

teardown 함수: 모든 테스트가 완료된 후 정리 작업을 수행합니다. 생성한 테스트 데이터를 삭제하거나 연결을 종료할 수 있습니다.

주의: VU와 반복 횟수VU(Virtual User) 수는 동시 사용자 수를 나타냅니다. 만약 1개의 VU가 1분 동안 테스트를 실행하고 sleep(1)이 있으면 약 60번의 반복이 일어납니다. 이는 단순 계산으로 VU 수 곱하기 반복 횟수입니다. 예를 들어 10개의 VU가 1분간 테스트하면 약 600번의 요청이 발생합니다.
k6 스크립트 작성
그림 3: load-test.js 스크립트 작성 및 기본 구조

실행 및 결과 분석

작성한 k6 스크립트를 실행하고 결과를 분석하는 방법을 배웁니다. k6은 상세한 성능 지표를 제공하여 시스템의 성능 병목을 파악하는 데 도움이 됩니다. 결과 분석은 시스템 최적화의 첫 단계입니다.

테스트 실행

기본 실행 명령어
# 간단한 실행
k6 run load-test.js

# VU 수와 지속 시간 지정
k6 run --vus 50 --duration 1m load-test.js

# 상세 로그 출력
k6 run --verbose load-test.js

# 결과를 JSON으로 내보내기
k6 run --summary-export=result.json load-test.js

주요 성능 지표

k6이 제공하는 주요 메트릭은 다음과 같습니다:

지표명설명이상적인 범위
http_req_durationHTTP 요청의 응답 시간(ms)100-500ms
http_req_failed실패한 요청의 비율0-1%
http_reqs초당 처리한 요청 수(RPS)시스템에 따라 다름
vus활성 가상 사용자 수설정된 값
vus_max최대 가상 사용자 수설정된 값

결과 해석

테스트 완료 후 다음과 같은 정보를 얻습니다:

  • p(95): 95%의 요청이 이 시간 이내에 완료됨. 일반 사용자의 경험을 나타냄.
  • p(99): 99%의 요청이 이 시간 이내에 완료됨. 거의 모든 사용자의 경험을 나타냄.
  • Min/Max: 최소/최대 응답 시간. 이상치를 찾는 데 도움이 됨.
  • Avg: 평균 응답 시간. 전반적인 성능을 나타냄.
  • Med: 중앙값 응답 시간. 평균에 영향받지 않는 대표값.
k6 테스트 결과
그림 4: k6 테스트 실행 결과 및 상세 메트릭

결과 내보내기

JSON 포맷 결과 저장
k6 run --out json=output.json load-test.js

생성된 JSON 파일을 InfluxDB나 다른 분석 도구로 전송하여 더 상세한 분석이 가능합니다. 이렇게 하면 시계열 데이터로 성능 추이를 분석할 수 있습니다.

실제 테스트 캡쳐 화면

아래는 실제 macOS 환경(Mac mini, Apple Silicon)에서 k6를 설치하고 부하 테스트를 실행한 실제 터미널 캡쳐 화면입니다. 시뮬레이션이 아닌 진짜 실행 결과이므로 여러분의 환경에서도 동일한 결과를 얻을 수 있습니다.

k6 brew install 실행 화면 (macOS 실제 캡쳐)

▲ k6 brew install 실행 화면 (macOS 실제 캡쳐)

k6 version 확인 - v1.7.1 (darwin/arm64)

▲ k6 version 확인 - v1.7.1 (darwin/arm64)

k6 run load-test.js 실행 시작 화면

▲ k6 run load-test.js 실행 시작 화면

k6 부하 테스트 완료 - 전체 결과 리포트

▲ k6 부하 테스트 완료 - 전체 결과 리포트

k6 run --summary-export 결과 JSON 내보내기

▲ k6 run --summary-export 결과 JSON 내보내기

k6 run --vus 20 --duration 30s 고부하 테스트 결과

▲ k6 run --vus 20 --duration 30s 고부하 테스트 결과

Case 1: 스트레스 테스트

스트레스 테스트는 시스템이 점진적으로 증가하는 부하를 견딜 수 있는 한계점을 찾는 테스트입니다. 정상 범위를 초과하는 부하를 계속 증가시키면서 시스템의 동작을 관찰합니다. 이는 시스템의 최대 처리 용량을 파악하는 데 매우 중요합니다.

스트레스 테스트 목표

  • 시스템이 수용할 수 있는 최대 부하 확인
  • 과부하 상황에서의 에러율 변화 추적
  • 리소스 고갈 시 시스템의 복구 능력 검증
  • 적절한 제한(rate limiting) 설정 확인
  • 캐시 크기와 데이터베이스 연결 풀 크기 최적화

스트레스 테스트 스크립트

stress-test.js
import http from "k6/http";
import { check } from "k6";

export const options = {
  stages: [
    { duration: "2m",  target: 50 },   // 2분간 50 VU
    { duration: "3m",  target: 100 },  // 3분간 100 VU
    { duration: "2m",  target: 200 },  // 2분간 200 VU
    { duration: "3m",  target: 200 },  // 3분간 200 VU 유지
    { duration: "2m",  target: 0 },    // 2분간 쿨다운
  ],
  thresholds: {
    http_req_duration: ["p(99)<3000"],
    http_req_failed: ["rate<0.05"],
  },
};

export default function () {
  const res = http.get("https://your-api.example.com/endpoint");
  check(res, {
    "status 200": (r) => r.status === 200,
    "duration < 500ms": (r) => r.timings.duration < 500,
  });
}

실행 및 분석

실행 명령어
k6 run --out json=stress-result.json stress-test.js

스트레스 테스트 결과를 보면 특정 VU 수에서 응답 시간과 에러율이 급증하는 지점을 발견할 수 있습니다. 이 지점이 시스템의 한계점(breaking point)입니다. 일반적으로 이 지점의 75% 정도를 정상 부하의 최대값으로 설정합니다.

스트레스 테스트 설정
그림 5: 스트레스 테스트 스크립트 작성
스트레스 테스트 결과
그림 6: 스트레스 테스트 결과 분석
팁: 결과 해석응답 시간이 갑자기 증가하는 구간을 주목하세요. 이 지점이 당신의 API 서버가 처리할 수 있는 최적의 부하입니다. 이 데이터를 기반으로 캐싱, 데이터베이스 최적화, 로드 밸런싱 등을 계획할 수 있습니다. 결과를 차트로 만들어 팀과 공유하면 의사결정에 큰 도움이 됩니다.

Case 2: 스파이크 테스트

스파이크 테스트는 갑작스러운 트래픽 증가를 시뮬레이션합니다. 예를 들어 유명 연예인이 언급한 제품, 플래시 세일, 또는 뉴스 보도 이후의 갑작스러운 트래픽 폭증을 테스트합니다. 실제 서비스에서 발생할 수 있는 상황을 미리 체험할 수 있습니다.

스파이크 테스트의 특징

스파이크 테스트 스크립트

spike-test.js
import http from "k6/http";
import { check, sleep } from "k6";

export const options = {
  stages: [
    { duration: "1m",  target: 5 },    // 평상시 트래픽
    { duration: "10s", target: 100 },  // 10초만에 100 VU 폭증!
    { duration: "2m",  target: 100 },  // 2분간 유지
    { duration: "10s", target: 5 },    // 급격히 감소
    { duration: "1m",  target: 5 },    // 복구 확인
    { duration: "10s", target: 0 },    // 종료
  ],
};

export default function () {
  const res = http.get("https://your-api.example.com/event");
  check(res, {
    "status 200": (r) => r.status === 200,
  });
  sleep(0.5);
}

모니터링 포인트

스파이크 테스트 설정
그림 7: 스파이크 테스트 스크립트 구성
스파이크 테스트 결과
그림 8: 스파이크 테스트 결과 분석
주의: 프로덕션 영향스파이크 테스트는 매우 높은 동시 연결 수를 생성합니다. 반드시 스테이징 환경에서만 실행하세요. 프로덕션 환경에서 실행할 경우 실제 사용자에게 영향을 미칠 수 있습니다. 만약 프로덕션에서 테스트해야 한다면 반드시 사전 공지와 운영 팀의 승인을 받아야 합니다.

Case 3: 인증 API 시나리오

실제 서비스에서는 단순한 GET 요청뿐만 아니라 로그인, 토큰 발급, 데이터 조회 등의 복잡한 시나리오가 필요합니다. 이 섹션에서는 인증 플로우를 포함한 현실적인 테스트를 작성합니다. JWT 토큰, OAuth, 세션 기반 인증 등 다양한 인증 방식을 지원할 수 있습니다.

인증 시나리오 플로우

  1. 로그인 API 호출로 인증 토큰 획득
  2. 응답에서 토큰 추출 및 검증
  3. 토큰을 이용한 인증된 API 호출
  4. 토큰 갱신(리프레시) 처리

인증 시나리오 스크립트

auth-scenario.js
import http from "k6/http";
import { check, sleep } from "k6";
import encoding from "k6/encoding";

export const options = {
  vus: 20,
  duration: "1m",
  thresholds: {
    http_req_duration: ["p(95)<1000"],
    http_req_failed: ["rate<0.01"],
  },
};

export default function () {
  // Step 1: 로그인 요청
  const loginRes = http.post(
    "https://api.example.com/auth/login",
    JSON.stringify({
      email: "loadtest@example.com",
      password: "test1234",
    }),
    {
      headers: { "Content-Type": "application/json" },
    }
  );

  check(loginRes, {
    "로그인 성공 (200)": (r) => r.status === 200,
    "토큰 존재": (r) => r.json("token") !== undefined,
  });

  // Step 2: 토큰으로 인증된 API 호출
  const token = loginRes.json("token");
  const profileRes = http.get(
    "https://api.example.com/me",
    {
      headers: { Authorization: "Bearer " + token },
    }
  );

  check(profileRes, {
    "프로필 조회 성공": (r) => r.status === 200,
    "응답 500ms 미만": (r) => r.timings.duration < 500,
  });

  sleep(1);
}

고급 시나리오: 동적 사용자

auth-scenario-advanced.js
import http from "k6/http";
import { check, sleep } from "k6";

export const options = {
  vus: 100,
  duration: "3m",
};

export default function () {
  const payload = JSON.stringify({
    name: "테스트 상품",
    quantity: Math.floor(Math.random() * 5) + 1,
    coupon: "SUMMER2026",
  });

  // 1. 장바구니 추가
  const addCart = http.post(
    "https://api.example.com/cart/add",
    payload,
    {
      headers: { "Content-Type": "application/json" },
    }
  );

  check(addCart, {
    "장바구니 추가 성공": (r) => r.status === 200,
  });

  sleep(1);

  // 2. 결제 요청
  const checkout = http.post(
    "https://api.example.com/checkout",
    JSON.stringify({ method: "card" }),
    {
      headers: { "Content-Type": "application/json" },
    }
  );

  check(checkout, {
    "결제 성공": (r) => r.status === 200,
    "결제 2초 미만": (r) => r.timings.duration < 2000,
  });

  sleep(2);
}
인증 API 시나리오
그림 9: 인증 시나리오 테스트 실행
팁: 토큰 만료 처리실제 시나리오에서는 토큰이 만료될 수 있습니다. 토큰 만료 시 자동으로 리프레시 토큰을 사용하여 새로운 토큰을 발급받는 로직을 추가하면 더욱 현실적인 테스트가 됩니다. 이렇게 하면 프로덕션 환경에서 발생할 수 있는 문제를 미리 발견할 수 있습니다.

k6 부하 테스트 흐름도

k6 테스트의 전체 구조와 각 단계의 흐름을 시각적으로 표현합니다. Mermaid 다이어그램을 통해 복잡한 프로세스를 이해하기 쉽게 구성했습니다.

1. 전체 테스트 워크플로우

flowchart TD A["테스트 스크립트 작성"] --> B{"환경 확인"} B -->|로컬 실행| C["k6 run 실행"] B -->|클라우드| D["k6 cloud run"] C --> E["VU 초기화"] D --> E E --> F["기본 함수 반복 실행"] F --> G{"부하 단계 완료?"} G -->|아니오| F G -->|예| H["메트릭 수집 및 분석"] H --> I["결과 리포트 생성"] I --> J{"Threshold 통과?"} J -->|PASS| K["배포 승인"] J -->|FAIL| L["병목 지점 파악 및 개선"] L --> A

2. 테스트 실행 시퀀스

sequenceDiagram participant Dev as Developer participant K6 as k6 Engine participant VU as Virtual Users participant API as Target Server Dev->>K6: k6 run script.js K6->>K6: options 파싱 K6->>VU: VU 생성 (target 수만큼) loop 각 VU 반복 실행 VU->>API: HTTP 요청 전송 API-->>VU: HTTP 응답 반환 VU->>VU: check() 응답 검증 VU->>K6: 메트릭 수집 VU->>VU: sleep() 대기 end K6->>K6: thresholds 평가 K6-->>Dev: 결과 리포트 출력

3. VU 부하 패턴 비교

graph LR A["부하 테스트 종류"] --> B["Smoke Test
1-2 VU, 1-2분"] A --> C["Load Test
10-100 VU, 5-15분"] A --> D["Stress Test
100-500 VU, 10-30분"] A --> E["Spike Test
즉시 200-500 VU"] A --> F["Soak Test
50 VU, 4-24시간"]
테스트 흐름도
그림 10: k6 테스트 흐름도와 결과 내보내기

Grafana k6 Cloud 연동

Grafana k6 Cloud는 클라우드 기반 분산 부하 테스트 플랫폼입니다. 로컬에서 테스트하기 어려운 대규모 시뮬레이션을 전 세계 여러 리전에서 동시에 실행할 수 있습니다. 클라우드 기반이므로 인프라 관리 없이 바로 시작할 수 있습니다.

k6 Cloud의 장점

k6 Cloud 연동 절차

1단계: 로그인
k6 login cloud

명령어를 실행하면 브라우저에서 k6 클라우드 계정으로 로그인하는 페이지가 열립니다. 계정이 없다면 무료로 가입할 수 있습니다. 소셜 로그인도 지원하므로 빠르게 시작할 수 있습니다.

2단계: 클라우드에서 테스트 실행
k6 cloud run load-test.js

이 명령어를 실행하면 로컬 스크립트가 k6 클라우드 플랫폼으로 전송되어 분산 실행됩니다. 전 세계 여러 리전의 서버에서 동시에 부하를 생성합니다.

클라우드 테스트 설정

cloud-test.js
import http from "k6/http";

export const options = {
  cloud: {
    projectID: 123456,
    name: "프로덕션 부하 테스트",
  },
  stages: [
    { duration: "2m", target: 50 },
    { duration: "5m", target: 50 },
    { duration: "2m", target: 0 },
  ],
};

export default function () {
  http.get("https://your-api.example.com/");
}

k6 Cloud의 이점

기능로컬 실행k6 Cloud
최대 VU 수로컬 리소스 제한1000 이상
분산 테스트불가능전 세계 리전
결과 저장수동 관리자동 저장
성능 비교수동 비교자동 비교
비용무료유료(무료 쿼터 제공)
Grafana k6 Cloud
그림 11: Grafana k6 Cloud 대시보드

k6 vs 다른 도구 비교

부하 테스트 도구는 여러 가지가 있습니다. k6의 특징과 다른 도구들과의 차이점을 비교하여 프로젝트에 적합한 도구를 선택할 수 있도록 합니다. 각 도구는 고유한 장단점이 있으므로 프로젝트의 요구사항에 맞게 선택해야 합니다.

주요 부하 테스트 도구 비교

항목k6JMeterLocustGatling
개발사Grafana LabsApache오픈소스Gatling
스크립트 언어JavaScriptJavaPythonScala
학습 난이도낮음높음중간높음
성능매우 좋음보통보통좋음
분산 테스트클라우드(유료)마스터-슬레이브직접 구현가능
GUI없음있음없음웹 기반
클라우드 지원Grafana Cloud없음없음자체
라이센스오픈소스 + 상용Apache 2.0오픈소스상용

도구별 추천 사용 시나리오

k6를 추천하는 경우

JMeter를 추천하는 경우

Locust를 추천하는 경우

도구 비교
그림 12: 부하 테스트 도구 비교 분석

실무 팁과 주의사항

실제 프로젝트에서 k6을 사용할 때 고려해야 할 중요한 팁과 주의사항을 정리했습니다. 이러한 내용을 숙지하면 더욱 효과적인 부하 테스트를 수행할 수 있습니다. 경험에서 우러나온 실무 지혜들입니다.

1. 테스트 환경 분리

부하 테스트는 항상 스테이징 환경에서만 수행하세요. 프로덕션 환경에서 부하 테스트를 실행하면 실제 사용자에게 영향을 미쳐 서비스 장애로 이어질 수 있습니다. 스테이징 환경의 설정이 프로덕션과 최대한 비슷해야 정확한 결과를 얻을 수 있습니다.

중요: 프로덕션 부하 테스트는 반드시 운영 팀의 승인과 사전 공지 후에 진행하세요.

2. 점진적 부하 증가

부하를 한 번에 대폭 증가시키지 마세요. 점진적으로 증가시켜서 시스템의 동작을 면밀히 관찰하세요. 이렇게 하면 병목 지점을 더 정확하게 파악할 수 있습니다.

올바른 단계: 10 VU → 50 VU → 100 VU → 200 VU 형태로 천천히 증가시키세요.

3. 적절한 thresholds 설정

Threshold는 테스트 성공/실패를 결정하는 중요한 조건입니다. 현실적이고 달성 가능한 값을 설정하세요. 너무 엄격한 threshold는 의미 있는 테스트를 방해합니다.

좋은 threshold 예
thresholds: {
  http_req_duration: ["p(95)<500", "p(99)<1000"],
  http_req_failed: ["rate<0.01"],    // 1% 미만 허용
  http_req_connecting: ["p(95)<100"], // 연결 시간 제한
  checks: ["rate>0.95"],               // 체크 통과율 95%
}

4. 데이터베이스 인덱싱 확인

부하 테스트 중 데이터베이스 성능이 저하된다면, 인덱싱을 확인하세요. 자주 조회되는 필드에 인덱스가 있는지 검증하세요. 인덱스 없는 풀 스캔은 부하의 주요 원인입니다.

5. 캐싱 전략

Redis, Memcached 등의 캐시를 적절히 활용하면 데이터베이스 부하를 크게 줄일 수 있습니다. 캐시 전략을 사전에 잘 수립하면 응답 시간을 획기적으로 개선할 수 있습니다.

6. 연결 풀 설정

데이터베이스 연결 풀 크기를 적절히 설정하세요. 너무 작으면 병목이 되고, 너무 크면 메모리를 낭비합니다. 일반적으로 동시 사용자 수의 25% 정도가 적절합니다.

7. 로그 수준 조정

테스트 중에는 로그 수준을 낮추세요. 과도한 로깅도 시스템 성능에 영향을 미칩니다. INFO 수준을 ERROR로 변경하면 I/O 부하를 줄일 수 있습니다.

8. 메모리 누수 모니터링

장시간 테스트(Soak Test)를 실행할 때는 메모리 사용량이 계속 증가하지 않는지 모니터링하세요. 메모리 누수가 있으면 발견할 수 있습니다. Grafana를 통해 메모리 그래프를 실시간으로 확인하세요.

9. 다양한 시나리오 테스트

단순 부하 테스트뿐만 아니라 다양한 시나리오(Smoke, Load, Stress, Spike, Soak)를 모두 테스트하세요. 각 시나리오는 다른 문제를 노출합니다.

10. 결과 분석 및 기록

테스트 결과를 상세히 기록하고, 이전 결과와 비교하여 성능 변화 추이를 파악하세요. 이는 성능 개선의 효과를 정량적으로 증명할 수 있습니다.

팁: k6 cloud의 비교 기능을 사용하면 자동으로 이전 결과와 비교할 수 있습니다. 이렇게 하면 성능 개선을 추적하기가 훨씬 쉬워집니다.

자주 묻는 질문 (FAQ)

k6 사용 중 자주 나오는 질문들을 모아 정리했습니다. 여기서 답변을 찾지 못하면 공식 문서나 커뮤니티에 문의하세요. 활발한 커뮤니티에서 많은 도움을 받을 수 있습니다.

Q. k6을 무료로 사용할 수 있나요?

네, k6 오픈소스는 완전히 무료입니다. 로컬 환경에서 제한 없이 부하 테스트를 실행할 수 있습니다. 다만 k6 Cloud는 유료 서비스입니다. 월 100만 개의 요청까지는 무료 쿼터를 사용할 수 있으므로 소규모 프로젝트에는 충분합니다. 대규모 프로젝트의 경우 합리적인 가격으로 이용할 수 있습니다.

Q. 최대 몇 개의 VU를 동시에 실행할 수 있나요?

로컬 실행 시에는 머신의 리소스에 따라 다릅니다. 일반적으로 한 머신에서 수천 개의 VU를 실행할 수 있습니다. 그 이상의 규모가 필요하면 k6 Cloud를 사용하거나 여러 머신에서 분산 실행을 구성해야 합니다. k6 Cloud의 경우 최대 10000개 이상의 VU를 지원합니다. 개별 리전당 VU 수에는 제한이 있지만 여러 리전을 조합하면 아주 큰 규모의 테스트도 가능합니다.

Q. 인증 토큰을 관리하는 최적의 방법은?

환경 변수를 사용하여 토큰을 관리하세요. 스크립트 내에 하드코딩하면 안 됩니다. 다음과 같이 사용할 수 있습니다:

const token = __ENV.API_TOKEN;

실행 시 다음과 같이 전달합니다:

k6 run --env API_TOKEN="your_token" script.js

이렇게 하면 토큰 정보가 스크립트 파일에 남지 않아 보안이 강화됩니다. 특히 Git에 커밋할 때 민감한 정보가 포함되는 것을 방지할 수 있습니다.

Q. 테스트 중에 CSV 파일에서 데이터를 읽을 수 있나요?

네, k6은 CSV 파일 읽기를 지원합니다. SharedArray와 함께 사용하면 모든 VU가 데이터를 공유할 수 있습니다:

import { SharedArray } from "k6/data";

이렇게 하면 각 VU가 CSV의 다른 행을 읽어서 다양한 데이터로 테스트할 수 있습니다. 사용자 계정 테스트, 상품 ID 테스트 등에 유용합니다.

Q. k6 테스트 결과를 Grafana와 연동할 수 있나요?

네, k6은 InfluxDB로 메트릭을 내보낼 수 있으며, Grafana에서 InfluxDB를 데이터 소스로 연결하여 대시보드를 만들 수 있습니다. k6 Cloud를 사용하면 기본으로 Grafana 통합이 제공됩니다. 다음과 같이 실행합니다:

k6 run --out influxdb=http://localhost:8086/k6 script.js

이렇게 하면 테스트 중 수집한 모든 메트릭이 InfluxDB에 저장되고 Grafana에서 아름다운 대시보드로 시각화할 수 있습니다.

반응형

'공부' 카테고리의 다른 글

MSA란? 채용 공고에서 자주 보이는 마이크로서비스 아키텍처 이해하기  (0) 2026.06.03
k6 + Grafana 연계 및 응용 사용 후기 — InfluxDB로 실시간 부하테스트 대시보드 구축하기  (0) 2026.04.14
Qdrant와 LLM을 활용한 고객지원 티켓 검색 시스템 구축기  (0) 2025.10.02
Web Worker로 UI 멈춤 문제 해결하기  (0) 2025.04.02
Vite vs Webpack: 어느 번들러를 선택할 것인가?  (1) 2025.04.02

Categories