목차 열기
부하테스트 개요
PlayBall 백엔드는 staging 환경(AWS)에서 k6 기반 부하테스트를 3일간 수행했습니다. AS-IS 베이스라인 측정부터 Phase 1~4 최적화까지, 각 단계의 병목 지점과 개선 효과를 수치로 검증했습니다.
1. 테스트 환경
1.1 인프라 스펙
| 구분 | 스펙 | 비고 |
|---|---|---|
| 환경 | staging (AWS) | api.staging.playball.one |
| DB 인스턴스 | db.t4g.small (PostgreSQL 16) | max_connections = 270 — 실제 한계선 |
| Redis (공용) | ElastiCache Redis 7 | 인증·분산락·캐시 |
| Redis (Queue) | ElastiCache Redis 7 (별도) | 대기열 ZSET 전용 |
| Kafka | Apache Kafka 3.7.1 | 이벤트 메시징 |
| Kubernetes | EKS (Istio Gateway + mTLS) | Envoy Proxy |
1.2 서비스별 포트/역할
| 서비스 | 포트 | 역할 |
|---|---|---|
| API-Gateway | 8085 | JWT 중앙 검증, 라우팅, Rate Limiting, 봇 차단 |
| Auth-Guard | 8080 | Kakao OAuth, JWT 발급/갱신(RTR), 유저 차단 |
| Queue | 8081 | Redis ZSET 대기열, Admission Token 발급 |
| Seat | 8082 | 좌석 추천/배정, Redisson 분산 락, Hold 관리 |
| Order-Core | 8083 | 주문 생성, 결제 처리, 마이페이지 |
1.3 기술 스택
- Java 21 LTS, Spring Boot 4.0.2, Spring Cloud 2025.1.1
- PostgreSQL 16 (HikariCP), Redis 7, Kafka 3.7.1
- Caffeine 3.x (로컬 캐시), Redisson 3.44.0 (분산 락)
- Resilience4j (Retry, Circuit Breaker)
2. 테스트 도구: k6
k6는 Grafana Labs의 Go 기반 오픈소스 부하 테스트 도구입니다. JavaScript로 테스트 시나리오를 작성하며, 수천 VU(Virtual User) 동시 시뮬레이션에 최적화되어 있습니다.
2.1 기본 개념
| 개념 | 의미 |
|---|---|
| VU (Virtual User) | 가상 사용자. 한 VU는 1개 스레드에서 순차적으로 요청을 반복 실행 |
| Iteration | VU가 시나리오를 1회 실행하는 단위 |
| Duration | 테스트 총 실행 시간 |
| Ramp-up | VU를 점진적으로 늘리는 구간 |
| RPS | Requests Per Second (초당 요청 수) |
| Percentile (P50/P95/P99) | 응답 시간 분포에서 하위 50%/95%/99% 지점의 값 |
2.2 본 프로젝트의 k6 Controller
- 저장소:
304-goormgb-k6-operators - 각 Flow 시나리오:
k6-controller/scripts/{auth|queue|seat|recommendation|order}/flow.js - 웹 UI에서 VU/Duration 설정 후 실행 → 실시간 대시보드로 결과 확인
- 결과:
k6-test-result-{timestamp}_load.md형태로 저장
3. 측정 메트릭
3.1 HTTP 레벨
| 메트릭 | 설명 | 목표 |
|---|---|---|
http_reqs | 총 요청 수 | — |
http_req_duration | 요청 완료까지 소요 시간 | — |
http_req_duration{p50} | 중앙값 응답 시간 | — |
http_req_duration{p95} | 상위 95% 응답 시간 | < 1,000ms |
http_req_duration{p99} | 상위 99% 응답 시간 | < 2,000ms |
http_req_failed | 실패율 | < 1% |
3.2 상태 코드 분포
| 상태 | 의미 | 주의 |
|---|---|---|
| 2xx | 성공 | — |
| 400 | 잘못된 요청 | DTO 유효성 검증 실패 |
| 401 | 인증 실패 | 토큰 만료/위조 |
| 403 | 권한 없음 | 봇 차단, Rate Limit |
| 404 | 리소스 없음 | 연석 부족, Admission Token 만료 |
| 409 | 충돌 (경합) | 좌석 Hold 경합 — 정상 동시성 제어 결과 |
| 410 | Gone | Admission Token 만료 |
| 429 | Too Many Requests | Rate Limiting 동작 |
| 503 | Service Unavailable | Envoy upstream connect timeout — 병목 신호 |
3.3 k6 Custom Metrics (본 프로젝트 전용)
큐 관련
queue_ready_count: 대기열에서 READY 상태로 승격된 VU 수queue_fail_count: READY 실패 VU 수queue_wait_seconds: 큐 진입 → READY까지 실제 대기 시간
추천 배정 관련
rec_assign_success: 좌석 배정 성공 수rec_assign_contention: 409 경합 발생 수rec_assign_no_seat: 404 연석 없음rec_real_consecutive: 실연석 배정 성공rec_semi_consecutive: 준연석 배정 성공
좌석 Hold (포도알) 관련
seat_hold_final_success: 재시도 포함 최종 성공 VUseat_hold_final_fail: 모든 블럭 시도 후 실패 VUseat_hold_contention: 이선좌(409) 총 발생 건수seat_hold_attempts: VU당 시도 횟수 분포
4. 백엔드 모니터링 지표
k6 외부 측정값과 함께, 백엔드 내부 지표도 Prometheus로 수집합니다.
4.1 DB 관련
| 지표 | 의미 |
|---|---|
hikaricp_connections_active | 현재 사용 중인 커넥션 수 |
hikaricp_connections_idle | 유휴 커넥션 수 |
hikaricp_connections_pending | 커넥션 획득을 기다리는 스레드 수 (핵심 지표) |
hikaricp_connections_max | 풀 최대 크기 |
postgres_max_connections | DB 서버 측 최대 연결 수 (270) |
rds_cpu_utilization | RDS CPU 사용률 |
4.2 JVM / Tomcat
| 지표 | 의미 |
|---|---|
jvm_threads_live | 전체 JVM 스레드 수 |
tomcat_threads_busy | 작업 중인 Tomcat 워커 스레드 수 |
tomcat_threads_max | Tomcat 최대 워커 수 (설정값) |
tomcat_connections_current | 현재 TCP 연결 수 |
tomcat_sessions_active | 활성 세션 수 |
4.3 캐시 관련
| 지표 | 의미 |
|---|---|
cache_gets{result=hit} | Caffeine 캐시 hit 수 |
cache_gets{result=miss} | Caffeine 캐시 miss 수 |
cache_evictions | eviction 발생 수 |
cache_size | 현재 캐시 엔트리 수 |
| — 조회 경로 | /actuator/metrics/cache.gets |
4.4 Redis / 분산 락
| 지표 | 의미 |
|---|---|
ticketing_seat_lock_wait_seconds | Redisson 분산 락 획득 대기 시간 |
ticketing_seat_hold_fail_total{reason} | Hold 실패 사유별 카운터 |
ticketing_seat_recommend_degrade_total | 준연석 폴백 발생 |
5. 부하 패턴
k6 실행 시 3단계 패턴을 사용합니다.
VU 수
▲
│
1000│ ┌─────────────┐
│ / \
│ / \
0└─────────/─────────────────\─────── 시간 →
Ramp-up 유지 Ramp-down
~30s ~2~3min ~30s- Ramp-up: VU를 0 → 목표치까지 점진적으로 증가 (급격한 부하로 인한 오탐 방지)
- 유지 (Steady state): 목표 VU를 일정 시간 유지 (성능 측정 구간)
- Ramp-down: 정상 종료
6. 3일간 테스트 시간표
| 일자 | 단계 | 내용 |
|---|---|---|
| 2026-04-14 | 01~03 | AS-IS 베이스라인 측정 (아무 최적화 없는 상태) |
| 2026-04-15 | 04~15 | 1차 Caffeine 캐싱, Phase 1~2 적용 및 검증 |
| 2026-04-16 | 16~21 | Phase 3~4 완료 후 엔드투엔드 검증, 추천 ON/OFF 전체 플로우 |
각 단계별 상세 결과는 테스트별 결과 요약 페이지를 참조하세요.