부하 테스트 시나리오 설계 및 구현 - 100-hours-a-week/KTB4-16th-Cloud GitHub Wiki
부하 테스트 대상 API · 트래픽 기준 · 시나리오 설계 (v1)
배경
별도의 개발/스테이징 서버가 없어, Blue-Green 배포 구조상 항상 하나는 대기 상태인 standby VM을 부하테스트 대상으로 삼는다. AI/외부 API(날씨, 추천, 음악검색)는 비용, 레이트리밋 문제로 이번 범위에서 제외한다.
1. 부하테스트 대상 API 선정
실제 배포된 백엔드 API 전체에서, AI/외부 API 의존 없이 서비스 핵심 흐름을 이루는 엔드포인트를 선정했다.
| # | API | 선정 사유 |
|---|---|---|
| 1 | GET /api/csrf | 모든 인증 요청의 선행 단계, 트래픽 최상단 |
| 2 | POST /api/users/signup | 신규 유저 유입 경로 |
| 3 | POST /api/auth/login | 모든 세션의 진입점, 가장 빈도 높은 인증 트래픽 |
| 4 | POST /api/auth/refresh | 세션 유지 중 반복 호출되는 백그라운드 트래픽 |
| 5 | POST /api/auth/logout | 세션 종료 |
| 6 | GET /api/users/me | 마이페이지 진입 시 항상 호출 |
| 7 | POST /api/uploads | 기록 생성의 필수 선행 단계 (GCS 업로드 포함, 병목 후보) |
| 8 | POST /api/records | 핵심 쓰기 트래픽 (기록/자물쇠 생성) |
| 9 | GET /api/records | 지역별 기록 목록 조회 — 핵심 읽기 트래픽, 최다 호출 예상 |
| 10 | GET /api/records/regions | 지역 목록 조회 |
| 11 | GET /api/records/{recordId} | 기록 상세 조회 |
| 12 | DELETE /api/records/{recordId} | 삭제 트래픽 |
| 13 | GET /api/places/popular | 지도 화면 진입 시 호출 |
| 14 | POST /api/users/me/records/search | 마이페이지 내 기록 검색 |
제외한 API: /api/weather, /api/recommendations/, /api/music/search, /api/places/popular-tracks/search, /api/monthly-reports — 외부 API(기상청/Spotify/LLM) 호출을 포함하거나 그 결과에 의존하기 때문.
2. 트래픽 기준 선정
v1 트래픽 추정 문서 기준.
| 지표 | 값 | 산정 근거 |
|---|---|---|
| 총 사용자 / MAU | 2만 명 | 릴스 홍보 1만 + 추가 캠페인 4천 + 2차 확산 7.5천 (셋로그 대비 보수적 절반 수준) |
| DAU | 5,000명 | MAU × 25% |
| TS(체류시간) | 1분 20초 | 목업 실측(기록 생성 45초+지도 확인 20초+플레이리스트 10초) |
| ACU | 약 6명 | (DAU × 평균 세션시간) ÷ 하루 활동시간 |
| MCU | 약 18명 | ACU × 피크 배수 3배 |
| 평시 목표 RPS/TPS | 1.1 / 0.11 | ACU × (세션당 요청·트랜잭션 수 ÷ 세션 시간) |
| 피크 목표 RPS/TPS | 3.4 / 0.32 | MCU × (세션당 요청·트랜잭션 수 ÷ 세션 시간) |
VU 수는 ACU/MCU를 그대로 사용 (동시접속자 수 = VU 수, 별도 배율 없음).
3. 시나리오 설계
공통 User Flow — 페르소나(퇴근길에 현재 음악을 기록하고 플레이리스트를 추천받는 20대 여성)의 세션당 요청 수 산정을 그대로 반영 (AI 의존 4개 제외):
GET /api/csrf → POST /api/auth/login → GET /api/users/me
[지도에서 자물쇠 확인, 약 7회]
GET /api/places/popular (초기 로드) × 1
GET /api/places/popular (지역 클릭→인기음악, 좌표 이동으로 근사) × 3
GET /api/records?legalDongCode=... (내 자물쇠 보기 토글) × 1
GET /api/records/{id} (상세 조회) × 최대 2
[자물쇠 생성 — 사진 첨부율 50%를 발생 확률로 사용]
50%: POST /api/uploads → POST /api/records
(테스트 데이터 정리용 DELETE 추가 — 실제 페르소나 행동 아님)
POST /api/auth/logout
| 시나리오 | 목적 | VU 프로파일 | 지속시간 | 통과 기준 |
|---|---|---|---|---|
| Normal | ACU(6명) 수준 정상 동작 확인 | 0→6(1분)→6 유지(5분)→0(1분) | 7분 | p95<500ms, 에러율<1%, 목표 RPS 1.1 근접 |
| Peak | MCU(18명, ACU×3) 수준에서도 버티는지 확인 | 0→18(2분)→18 유지(5분)→0(2분) | 9분 | p95<800ms, 에러율<2%, 목표 RPS 3.4 근접 |
| Stress | MCU 이상 브레이킹 포인트 탐색 | 18→50→100→200 (단계별 2분 증가, 2분 유지) | 20분 | 판정 없음(정보수집) — 에러율 5% 넘는 VU 수를 "한계 동시접속자"로 기록 |
| Spike | ACU 대비 순간 10배(60명) 급증 시 복원력 확인 | 6→60(10초 급증)→30초 유지→6(급감)→반복 2회 | 5분 | 스파이크 직후 5초 내 에러율 10% 이하 복귀, 종료 후 에러율 0 회복 |