장애 대응 보고서 및 부하 테스트
1. 개요
문서 목적
해당문서는 콘서트 좌석 예약 시스템의 API 성능 테스트 및 장애 대응 과정, 개선 방안을 정리한 보고서이다.
시스템 개요
대기열(Queue) 처리로 30초의 인위적 지연이 존재하지만, 이는 병목 요소가 아닌 의도된 대기임을 전제한다.
성능 테스트 개요
테스트 대상 API
POST /tokens/issue(토큰 발급)GET /tokens/status(대기열 상태 조회)GET /concerts/:id/dates/available(일정 조회)GET /concerts/:id/seats/available(좌석 조회)POST /reservations/:id/reserve-seats(좌석 예약)POST /reservations/:id/payment(결제)
테스트 시나리오
사용자별 토큰 발급
대기열 30초(인위적 지연)
콘서트 일정 및 좌석 조회
좌석 예약 및 결제 요청
각 API 단계별 응답 시간, 에러율 측정
테스트 환경
도구: k6 스크립트(
integration-test.js), Grafana 대시보드가상 유저(VU): 최대 300
목표 지표: 응답 시간(AVG, P95, P99), 에러율, 처리량(RPS), 커스텀 메트릭(
reserve_time,payment_time, 등)
2. 장애 발생 및 원인 분석
2.1. 전체 시스템 장애 발생 시나리오
일부 API에서 성능 저하가 감지
원인 분석
동시성 처리 미흡
기존 Redis Lock만으로는 다수의 동시 요청이 들어올 때 락 경합이 발생하여 응답 지연 및 실패가 증가
ReservationFacade의 예약/결제 로직에서 락 적용은 있었으나, 추가적인 낙관적 락 도입이 필요
쿼리 부하 및 인덱스 부재
예약/결제 관련 DB 쿼리에서 인덱스가 없던 부분이 있어, 풀 스캔 및 비효율적 쿼리 실행이 원인
캐시 전략
좌석 조회 및 일정 조회에서 캐시 적용이 미흡하여 동일 데이터에 대해 반복적으로 DB 접근이 발생
토큰 관리 방식 문제
기존에 토큰 관리를 DB에서 수행하던 방식은 응답 지연 및 동시성 문제를 야기
전체 시스템 지표 (개선 전)
3. 장애 해결 과정
3.1. 전체 시스템 개선 조치
✔️ 토큰 관리 개선
기존 DB에서 관리되던 토큰을 Redis로 전환하여, 빠른 조회 및 상태 변경이 가능하도록 개선
RedisTokenRepository, RedisTokenQueueRepository, TokenService 등을 활용해 Redis 기반 토큰 관리 체계를 구축
✔️ 동시성 처리 최적화
기존 Redis Lock 외에 낙관적 락(Optimistic Locking) 도입을 검토 및 적용하여, 동시 예약/결제 요청 시 락 경합을 최소화
ReservationFacade의 예약 및 결제 로직에서 락 적용을 강화
✔️ 쿼리 부하 개선
DB 쿼리 실행 계획(EXPLAIN ANALYZE)을 분석하여 비효율적인 쿼리를 최적화하고, Batch 처리 및 Lazy Loading 기법을 도입
예약/결제 관련 쿼리에서 불필요한 풀 스캔을 방지
✔️ 인덱스 최적화
기존 인덱스가 없던 부분에 대해 인덱스를 추가하여 쿼리 성능을 개선
concert_schedule 테이블:
concert_id, is_sold_out복합 인덱스 추가seat 테이블:
concert_id, schedule_date복합 인덱스 추가reservation 테이블:
user_id, status복합 인덱스 추가
✔️ 캐시 적용 강화
ConcertService에서 좌석 조회 시 @Cacheable을 활용하여 동일 데이터에 대한 반복 조회를 방지
Redis를 통한 토큰 관리와 함께 캐시 전략을 보완하여, 전체 시스템 응답 속도를 향상
4. 성능 테스트 시나리오 및 결과
4-1. 성능 테스트 개요
테스트 대상 API
POST /tokens/issue(토큰 발급)GET /tokens/status(대기열 상태 조회)GET /concerts/:id/dates/available(일정 조회)GET /concerts/:id/seats/available(좌석 조회)POST /reservations/:id/reserve-seats(좌석 예약)POST /reservations/:id/payment(결제)
테스트 환경
도구: k6 스크립트(
integration-test.js), Grafana 대시보드가상 유저(VU): 최대 300
목표 지표: 응답 시간(AVG, P95, P99), 에러율, 처리량(RPS), 커스텀 메트릭(
reserve_time,payment_time, 등)
테스트 시나리오
사용자별 토큰 발급 (POST /tokens/issue)
의도적 30초 대기(대기열 처리 – 분석 대상에서 제외)
예약 가능한 일정 및 좌석 조회
좌석 예약 요청 (POST /reservations/:id/reserve-seats)
결제 요청 (POST /reservations/:id/payment)
테스트 시나리오 스크립트
4-1. 전체 시스템 지표 (개선 후)

/reservations/:id/payment(500)Count=1로 500 에러가 1건 발생
단발성 에러(테스트 중 특정 케이스)일 가능성이 높음
/reservations/:id/payment(200)다수의 정상 결제가 발생(예: COUNT=100+).
AVG는 수 ms수십 ms 정도로 보이지만, MAX가 최대 7초까지 치솟고, P95/P99 구간에서 37초대가 관측됨
일부 요청에서 병목이 발생했을 가능성이 크므로 모니터링 필요
/reservations/:id/reserve-seats(200)비교적 요청 수(Count)가 적은 편이지만, MIN/AVG/MAX 모두 수 ms 내외로 매우 빠른 응답
좌석 예약 로직이 생각 외로 빠르게 처리되는 케이스가 많음
concerts/:id/dates/available,/concerts/:id/seats/availableAVG가 ms 단위로 빠르지만, 간헐적으로 MAX가 수 초(최대 6s)까지 올라가는 경우가 존재
캐시 미스나 DB 일시 부하, 네트워크 지연 등 특정 상황에서의 지연 발생으로 유추
/tokens/issue,/tokens/status주로 AVG가 수 ms~수십 ms 수준으로 안정적
토큰 발급/상태 조회 로직이 Redis를 통한 캐싱/조회로 빠르게 동작하고 있음

Peak RPS: 약 208 RPS로, 트래픽이 몰리는 구간에서 초당 200건 이상의 요청
Max Response Time: 13.7초
Error Rate: 약 2.47% (HTTP Failures: 270건)
VU Max: 동시 접속자 300
Average Response Time: 504.01ms
Total Requests: 약 10910건 처리
대부분 요청은 평균 504ms 내로 처리되지만, 일부 요청이 최대 13.7초까지 지연됨
결제(payment) API: 대다수 요청은
수십 ms ~ 수백 ms이지만, 일부 요청이 7초 이상 지연되어 P95/P99 구간이 높음예약(reserve-seats) API: 응답 시간이 매우 짧고 안정적
일정/좌석 조회: 평균은 ms대이지만, 캐시 미스나 DB 부하 시 수 초 단위로 지연되는 사례 존재
토큰 발급/조회: Redis 전환 후 대체로 빠르고 안정적
5. 종합 평가 및 결론
5-1. 전체 시스템 성능 요약
안정성: 테스트 결과 HTTP 실패율(http_req_failed)은 약 2.47%로, 성공률은 약 97.5% (개선 필요)
확장성: 최대 300 VU(동시 사용자)에서 안정적으로 작동하였으며, 시나리오 테스트 기준으로는 초당 약 101건의 요청을 처리할 수 있음 (Queue 대기 시간 고려 필요)
응답성: 대부분의 API는 평균 285.73ms의 응답 시간을 보이나, 일부 요청에서는 최대 13.69초까지 지연된 사례 조회
일관성: 평균 응답 시간 대비 P95가 1.24초 등 일부 지연 사례가 존재하나, 전반적으로는 성능 유지
5-2. 최종 결론
토큰 발급, 일정 조회, 좌석 예약, 결제 프로세스 전체 성능 개선
트랜잭션 충돌과 캐싱 부족 문제 해결, 실패율 감소
인덱스 최적화를 통해 주요 API 응답 속도 개선
5-3. 개선 영역
응답 시간 일관성:
일부 API에서 95번째 백분위 응답 시간이 평균보다 크게 높아 개선 필요
에러 처리:
현재 성공률은 약 97.5%로, 에러 원인 분석 필요
Last updated