성능 테스트로 응답시간과 확장 한계 검증하기

성능 테스트의 부하·스트레스·스파이크 유형과 SLO, 계측, 병목 분석, k6 기반 부하 검증 방법을 정리한다.

2026-08-14 · 최초 발행 2025-12-17

트래픽이 몰리기 전에 확인해야 할 시스템의 한계

성능 테스트는 목표 트래픽에서 응답시간, 처리량, 자원 사용량, 오류율을 측정하고 검증하는 품질 보증 활동이다. 정상 부하에서 SLO를 지키는지 확인하는 데서 끝나지 않는다. 임계치를 넘었을 때 어디에서 무너지고, 부하가 다시 내려간 뒤 어떻게 회복하는지도 함께 본다.

응답시간은 평균값만으로 판단하기 어렵다. p95/p99 지연을 기준으로 타임아웃, 콜드스타트, GC 영향을 분리해 살펴야 한다. 처리량은 초당 요청·트랜잭션(RPS/TPS)으로 확인하며 동시성, 큐 길이, 백프레셔와 연결된다. CPU, 메모리, 디스크 I/O, 네트워크 대역폭 같은 자원 지표는 컨테이너의 CPU 쿼터와 cgroup 제한까지 고려 대상이다.

부하 테스트는 목표 부하에서 성능과 SLO 준수 여부를 확인한다. 스트레스 테스트는 임계치를 초과했을 때의 붕괴 지점과 복구 특성을 드러낸다. 스파이크 테스트는 부하가 급격히 증가하거나 감소할 때 탄력성과 오토스케일 반응을 검증한다.

시나리오와 계측이 결과의 신뢰도를 만든다

부하 모델은 오픈 모델과 클로즈드 모델 중에서 선택한다. 오픈 모델은 도착률을 고정하고, 클로즈드 모델은 동시 사용자 수를 고정한다. 실제 트래픽의 피크·오프피크와 버스트 특성을 반영하지 않으면 테스트 결과도 운영 환경과 멀어진다.

시나리오는 사용자 여정을 따라 구성하고, 캐시 워밍과 데이터 시딩은 별도로 다룬다. 읽기와 쓰기의 비율도 명시해야 한다. 테스트 환경은 이미지, 설정, 스케일 구성이 프로덕션과 유사해야 하며 데이터 볼륨과 인덱스 상태 역시 맞춰야 한다.

분산 트레이싱(APM), 시스템 메트릭(Prometheus), 로그 상관키를 함께 사용하면 요청 경로 전체에서 병목을 찾을 수 있다. 현재 성능을 베이스라인으로 기록해 두면 회귀를 탐지할 수 있고, SLI에는 p95 응답시간, 오류율, 스레드풀 대기율을 둘 수 있다. SLO는 비즈니스 임팩트를 기준으로 정량화한 뒤 알람과 파이프라인 게이팅에 연결한다.

병목을 분류하고 튜닝을 반복하는 흐름

병목은 CPU 바운드, 디스크·네트워크 I/O 바운드, 락 경합·컨텐션, 외부 의존성 대기로 나눠 볼 수 있다. DB 커넥션 풀 고갈, 락 대기, 타임아웃 경합은 우선 확인할 항목이다.

튜닝은 알고리즘·쿼리 최적화부터 시작해 캐싱·배치, 풀 사이즈·큐, 스케일 아웃·업 순서로 검토한다. 임계치를 초과하면 병목 분석과 튜닝으로 되돌아가고, 장애나 오류율 급증이 발생하면 데이터를 수집한 뒤 즉시 롤백 절차를 수행한다.

아니오입력: 요구사항, 'SLO/SLI',트래픽 프로파일계획: 대상, 시나리오,부하모델('오픈/클로즈드')환경 준비: '프로덕션 유사구성', 데이터 시딩, 네트워크제약재실행모니터링:'응답시간(p95/p99)','처리량(TPS/RPS)','자원(CPU/메모리/IO)', 오류율임계 초과?병목 분석: 'CPU 프로파일',쿼리 플랜, '락/대기'승인: 베이스라인 업데이트튜닝: 코드 최적화, 캐시,사이즈, '스케일 아웃/업'보고: 결과 공유, 용량 계획,비용 추정

부하 변화에 따라 달라지는 검증 관점

테스트 유형 목적 성능 확장성 일관성 안정성 운영 편의
부하(Load) 목표 부하에서 SLO 검증 p95/p99 응답시간 확인 수평/수직 스케일 효율 측정 결과 재현성 높음 정상 상태 유지 확인 스케줄링·자동화 용이
스트레스(Stress) 임계 초과 시 붕괴점 파악 성능 저하 구간 탐지 한계 용량·병목 식별 재현성 중간(외부 변수 영향) 장애 전이·복구 특성 시나리오화 리스크 컨트롤 필요
스파이크(Spike) 급증/급감 반응성 검증 콜드 스타트·버스트 처리 확인 오토스케일 지연 평가 재현성 낮음(타이밍 민감) 서킷 브레이커·큐 흡수력 확인 스크립트/타이밍 정교화 필요

서비스 경로별로 보는 점검 대상

대규모 API 백엔드에서는 로그인 → 목록 조회 → 상세 조회를 80:15:5 비율의 읽기 중심 시나리오로 구성할 수 있다. DB 인덱스, 캐시 전략, 스레드·커넥션 풀, 타임아웃·재시도 정책이 주요 조치 지점이다.

데이터 처리 파이프라인은 배치·스트리밍 처리량 한계와 지연 상한을 검증한다. 메시지 큐의 백프레셔 설정, 스토리지 IOPS·스루풋 제한, 체크포인트·리트라이 정책을 함께 점검한다.

프론트엔드와 에지에서는 CDN 캐시 적중률 변화가 오리진 부하에 미치는 영향을 확인한다. TTFB와 서버 대기시간을 분리해 분석하고, Web Vitals와 서버 응답시간을 연결한 모니터링 구성이 필요하다.

격리 환경, 비용, 데이터 보호의 균형

프로덕션과 같은 환경이 이상적이지만 비용이 늘어난다. 핵심 경로부터 동형 환경으로 맞추는 전략이 필요하다. 도구 선택에서도 오픈 소스는 유연성을, 매니지드 도구는 운영 안정성을 제공한다. 초기에는 k6/JMeter를 쓰고 운영이 안정된 뒤 SaaS로 이전하는 방식도 가능하다.

실제 데이터 사용은 금지하고 합성 데이터 또는 포맷·분포 보존 마스킹을 적용한다. 테스트 중에는 서킷 브레이커, 레이트 리미트, 타임아웃 기본값을 강화한다. 알람을 임시로 약화하는 대신 대시보드 화이트리스트를 운영한다.

성능 테스트를 체계화하면 p95 응답시간은 2040% 개선되고 오류율은 30% 이상 감소할 수 있다. 튜닝·오토스케일 최적화를 기반으로 동일 처리량 대비 인프라 비용을 1025% 절감할 수 있으며, 용량 계획 오차 범위는 ±10~15% 내로 수렴한다. 릴리스 품질이 더 잘 보이고 성능 회귀를 일찍 발견할 수 있으며, 병목 유형을 표준화하면 조직의 학습 곡선과 협업 효율에도 영향을 준다.

k6로 부하와 스파이크를 함께 검증하는 예제

전제조건: k6 v0.49+ 설치, 대상 API 가용, 네트워크 제약 없음

// k6 run perf.js
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  thresholds: {
    http_req_duration: ['p(95)<500'],
    http_req_failed: ['rate<0.01'],
  },
  scenarios: {
    steady_load: {
      executor: 'ramping-arrival-rate',
      startRate: 100,
      timeUnit: '1s',
      preAllocatedVUs: 50,
      maxVUs: 500,
      stages: [
        { target: 300, duration: '5m' }, // 부하 상승
        { target: 300, duration: '10m' }, // 유지
        { target: 0, duration: '2m' }, // 하강
      ],
    },
    spike: {
      executor: 'externally-controlled', // k6 control API로 순간 스파이크 주입
    },
  },
};

const BASE = __ENV.BASE_URL || 'https://api.example.com';

export default function () {
  const res = http.get(`${BASE}/v1/items?limit=20`);
  check(res, {
    'status is 200': (r) => r.status === 200,
    'body not empty': (r) => r.body && r.body.length > 0,
  });
  sleep(1);
}

이 구성은 오픈 모델의 도착률로 실제 트래픽 패턴을 근사하고, externally-controlled로 스파이크 타이밍을 가변화한다. p95 응답시간과 실패율을 기준으로 게이트를 설정해 파이프라인을 자동 실패 처리할 수 있다.

성능 테스트부하 테스트SLOk6용량 계획