[STAGE] 대용량 트래픽 대응 공연 예매 시스템

과정
클라우드
노출 페이지
대표 이미지
대표이미지
서비스 한 줄 소개
회차
5 more properties

프로젝트 배경

STAGE는 Smart Ticketing & Gateway Experience의 약자로 공연 예매 서비스가 가지고 있는 가장 큰 특징인 대용량 트래픽에 초점을 맞춘 프로젝트입니다.
대용량 트래픽 대응
순간적인 트래픽에 따른 방대한 양의 데이터를 지연 없이 처리하는 아키텍처를 구성하고 싶었습니다.
서비스 안정성 최우선
어떠한 장애 상황에서도 서비스가 완전히 멈추지 않는 '연속성'을 확보하는 것이 핵심 과제였습니다.

핵심 목표

갑작스러운 트래픽 폭주에도 당황하지 않기
순간적으로 트래픽이 치솟는 환경에서 시스템이 안정적으로 요청을 처리하는 것을 목표로 합니다.
성장의 한계를 넘는 클라우드 아키텍처
필요에 따라 자원을 늘리고 줄일 수 있는 클라우드 기반의 아키텍처를 구현하여 비즈니스 성장에 맞춰 시스템도 함께 진화할 수 있게 합니다.
데이터 기반의 성능 극대화
직접 성능을 측정하고 수치를 개선하여 단위 시간당 처리량을 끌어올려야 합니다.
장애 격리를 통한 안정성 확보
서버의 일부가 고장 나더라도 전체 서비스가 중단되지 않도록 가용성을 높이고, 장애 복구력을 강화하여 사용자에게 끊김 없는 경험을 제공하고자 합니다.

프로젝트 소개

시연영상

1. 사용자 인터페이스

일반 로그인과 소셜 로그인 모두 구현
KOPIS API를 이용한 공연 상세 정보 수집 및 데이터 가공
BootPay를 이용한 결제 서비스 구축

2. 다수 사용자 가정 화면

좌석 락 처리 구현
사용자 대기 번호를 위한 실시간 통신 구축

3. Monitoring

Prometheus + Grafana로 클러스터/노드/Pod 리소스 실시간 모니터링
Loki로 MSA 서비스별 로그 중앙 수집 및 장애 추적
Promtail EOL 이슈로 OpenTelemetry Collector로 전환하여 로그 수집
AlertManager + Discord 연동으로 장애 즉시 알림
위험도별 알림 분리(Warning/Alarm) 및 분석 링크 제공

4. Infrastructure as Code

Terraform과 Ansible을 활용하여 운영 환경과 동일한 개발 환경 자동 구축
도메인 분리로 기존 운영 환경에 영향 없이 독립적인 테스트 가능

Architecture

Infra

다중 가용 영역(Multi-AZ) 기반의 고가용성 설계
두 개의 가용 영역을 사용하여 전체 시스템의 중단 없는 운영을 보장합니다. MySQL 데이터베이스를 Active/Standby 구조로 배치하여 고가용성을 확보했습니다. 또한, K3s 오토스케일링(HPA)을 적용하여 트래픽 변화에 따라 자원을 유연하게 확장/축소할 수 있도록 설계했습니다.
K3s를 활용한 경량 컨테이너 오케스트레이션
EKS 대신 EC2 인스턴스 내부에 k3s 클러스터를 구축하여 비용 효율성을 높였습니다. 또한, MSA 구조를 적용하여 특정 서비스 장애가 전체 시스템으로 확산되지 않도록 설계했습니다.
비동기 메시징 및 실시간 통신 처리 역량
SQS와 SNS를 활용한 비동기 메시징 시스템을 통해 서버의 안정성을 높였습니다. 동시에 WebSocket API를 통해 실시간 대기열 기능을 지원함으로써 사용자 경험을 동시에 고려했습니다.
ElastiCache(Redis OSS)를 활용한 고성능 분산 락 처리
동시성 제어가 중요한 기능에서 Redis를 활용해 분산 락을 구현하여 좌석 중복 점유 문제를 해결합니다. 이를 통해 대규모 트래픽 상황에서도 정합성을 유지하며 응답 속도를 극대화했습니다.

CI/CD

GitHub Organization 및 GHCR 중심의 통합 관리
GitHub Organization을 기반으로 프로젝트의 코드를 관리하고 협업 효율성 증대했습니다. 또한 GitHub Container Registry을 활용하여 도커 이미지를 관리했습니다. 결과적으로 GitHub 생태계 내부에서 코드 관리, 이미지 저장, 배포 트리거를 통합함으로써 도구 간의 컨텍스트 스위칭 감소 및 보안 연결 단순화했습니다.
GitOps 기반의 선언적 배포 및 리소스 최적화
매니페스트 파일과 클러스터의 실제 상태를 실시간으로 동기화하는 GitOps 구조 활용했습니다. kustomization.yaml을 통해 배포 프로세스 최적화하고 hpa.yaml 설정을 포함하여 오토스케일링 기능을 구현함으로써 가용성과 비용 효율성 확보했습니다.
보안 자동화가 통합된 CI 파이프라인
Semgrep(SAST)·Trivy를 CI에 통합해 취약점을 사전 차단하고 High/Critical 탐지 시 파이프라인을 실패 처리해 빌드·배포를 차단했습니다. DAST는 실행 시간·환경 의존성을 고려해 배포 전 OWASP ZAP 수동 점검으로 추가 검증했으며, 탐지된 취약점은 수정/설정 보완 후 재테스트로 조치 완료를 확인했습니다.

Infrastructure as Code

Terraform 기반 인프라 프로비저닝
Terraform으로 AWS 인프라 리소스를 코드로 정의했고 VPC, EC2, ALB, CloudFront, Route53 등을 자동 생성하는 시스템을 구현했습니다.
Terraform Workspace 기반 환경 분리
dev / front / back / prod / secret 으로 환경을 분리해서 관리했고 동일한 코드에서 Workspace 조건으로 리소스 선택적 생성 가능하도록 했습니다.
Ansible 기반 인프라 설정 자동화
EC2 생성 이후 반복되는 서버 설정 작업을 자동화했고 SSM 기반 접근으로 보안성 있는 구성으로 구축했습니다. 또한, AWS 태그 기반 Inventory 규칙으로 서버 그룹 자동 분류했습니다.
프로비저닝과 구성 관리 역할 분리
Terraform은 인프라 생성에 집중하고 Ansible은 서버 및 클러스터 설정에 집중하여 책임을 분리하는 구조를 구축했습니다.

Database

user_info → 회원 기본 정보
user_credential → 일반 로그인용 패스워드·잠금 정책
auth_provider → 인증 제공자 메타 정보
auth_info → 사용자가 연결한 외부 계정 및 토큰
show_detail → 공연 정보 조회 후 상세 정보
user_reservation → 회원이 예약한 좌석 정보 조회
seat → 공연 예매 정보

API 정리 표

메서드
API 엔드포인트
이름
서비스 도메인
부가 설명
POST
/api/v1/user/login
일반 로그인
user-service
이메일과 비밀번호를 사용
POST
/api/v1/user/change-password
비밀번호 변경
user-service
BCryptPasswordEncoder로 구현
GET
/api/v1/user/me
유저 정보 수정
user-service
유저 정보 수정(이름, 전화번호, 이메일)
POST
/api/v1/user/signup
회원가입
user-service
일반 회원가입 구현
GET
/api/v1/user/me
마이페이지
user-service
내 정보 및 내 예매 내역 확인
POST
/oauth2/authorization/naver
소셜로그인 - 네이버
user-service
네이버 소셜 로그인
POST
/oauth2/authorization/google
소셜로그인 - 구글
user-service
구글 소셜 로그인
POST
/api/v1/reserve/hold
좌석 예매
reserve-service
결제 전 임시 락
POST
/api/v1/reserve/reserve
좌석 확정
reserve-service
결제 후 공연 예매 성공
GET
/api/v1/reserve/enter
대기열 입장
reserve-service
좌석 선택 페이지 입장 여부 확인
GET
/api/v1/reserve/waiting_number
대기 번호 확인
reserve-service
웹소켓(대기번호)이 오지 않을 경우, 요청 방법
GET
/api/v1/reserve/seat_list
좌석 선택 페이지 입장
reserve-service
사용 중인 좌석 목록을 반환
GET
/api/v1/reserve/leave_seat
좌석 선택 페이지 떠남
reserve-service
좌석 선택 페이지 이탈
POST
/api/v1/payment/success
결제 완료
payment-service
결제 완료 시 서버로 영수증id 전송
POST
/api/v1/payment/callback
결제 웹훅
payment-service
외부 결제 서버로부터 결제 정보 획득
POST
/api/shows/fetch
기간별 공연 정보 수집
others-service
OPEN API를 사용한 공연 목록 수집
GET
/api/shows/fetch/{kopisId}
공연 상세 정보 수집
others-service
OPEN API를 사용한 공연 상세 정보 수집
GET
/api/v1/others/perform
공연 상세 페이지
others-service
공연 상세 정보 반환
GET
/api/v1/others/genres
장르 페이지
others-service
장르별 공연 페이지 반환
GET
/api/v1/others/earlyBird
얼리버드 페이지
others-service
최신 공연 반환
GET
/api/v1/others/
홈페이지
others-service
최신 공연 반환

기술 스택

Frontend : React, Javascript
Backend : SpringBoot, JPA, JWT
Database : MySQL, ElastiCache(Redis: SETNX, Sorted Set, TTL)
Messaging : AWS SQS, AWS SNS, Websocket API
Infrastructure : EC2, ALB, CloudFront, S3, VPC 등
CI/CD : Github Actions, Argo CD
Container: Docker
Reverse Proxy: Nginx
SecOps : Semgrep, Owasp ZAP, Trivy
Monitoring : Prometheus, Grafana, Loki, OTel
Iac : Terraform, Ansible
Load test : k6

협업 도구

Figma : UI/UX 디자인 설계 및 공유, 인프라 구성 공유
Notion : 일정 및 리소스 관리, 스프린트 및 이슈 관리
Canva, PPT : 발표 자료 공유 및 문서화
Discord : 음성 회의 및 화면 공유
Zoom : 정기 미팅, 실시간 커뮤니케이션
Github Organization : 소스 코드 관리
Swagger : API 문서화
Google Docs : 공동 문서 작업
AWS Cost Explorer, Compute Optimizer : 비용 최적화

핵심 컴포넌트

k3s

EC2 기반 K3s 클러스터 환경
EKS 대비 약 70% 비용 절감

SQS & SNS

비동기 이벤트 기반 통신
서버 간 결합도 감소 및 처리 안정성 개선

Elasticache Redis OSS & Websocket API

좌석 선택 시 결제 완료 전까지 임시 저장
실시간 좌석 상태를 여러 사용자에게 전파
사용자의 대기 상태 저장

k6

1차 테스트 조건 : 5m 500vu
병목 개선 후 2차 테스트 조건 : 30m 5000vu
Throughput 220% 향상
동시 접속 사용자 398명 → 880명

TroubleShooting

1)
문제 : 대기 번호 웹 소켓으로 부하 증가 우려
원인 : 일정 주기마다 전체 대기자에게 대기 번호를 일괄 전송하면서, 특정 시점에 WebSocket 메시지와 Redis 조회가 집중되어 순간적인 과부하
해결 방법 : 스케줄러를 도입하여 대기열 전체를 일정 시간 윈도우로 분할하고, 매 초 200~300명씩 분산 전송함으로써 WebSocket 메시지와 Redis 연산 부하를 분산 처리함.
2)
문제: Console로 작업한 기존 AWS 클라우드 환경을 Terraform으로 마이그레이션 필요
원인: Terraformer로 기존 인프라를 import 시도했으나 생성된 코드의 가독성이 낮고 모듈 구조가 비효율적이어서 유지보수가 어려웠음
해결 방법:
Terraformer가 생성한 코드는 리소스가 flat하게 나열되고, 변수명이 자동 생성되어 의미 파악이 어려워 그대로 사용 시 오히려 관리 부담이 증가한다고 판단
이에 따라 Terraform 코드를 모듈화하여 직접 설계 및 작성
단순 마이그레이션에 그치지 않고 활용도를 높이기 위해 Workspace 기반 환경 분리 도입
운영/개발 환경을 동일한 코드베이스로 독립 관리하여, 서로 영향 없이 인프라 변경 및 테스트 가능
3)
문제 : EKS와 RDS로 인한 예산 초과 문제
원인 : 프로젝트 초기부터 관리형 서비스(EKS, RDS) 도입으로 인해 예산 오버런 발생
해결 방법 :
기능 개발 단계에서 로컬 VM에 k3s 클러스터 환경을 직접 구축
Github Self-hosted Runner 이용한 CI/CD 파이프라인을 통해 비대면 환경임에도 팀원들 간 개발 환경 동일성 유지
운영 단계에서 클라우드로 마이그레이션 한 이후 EC2 내부에 k3s 클러스터 환경 구축
RDS를 대체하여 k3s 내에 MySQL 파드 운영
StatefulSet을 활용해 MySQL을 직접 운영하며, AWS EBS CSI Driver와 PVC를 연동하여 Pod 재시작 시에도 데이터가 유실되지 않고 안전하게 보존되도록 구성했습니다.

팀 소개

[Team Lead]

프로젝트 기획
인프라 아키텍처 설계
CI/CD 파이프라인 운영
부하 테스트 수행
이번 프로젝트는 트래픽이 집중되는 상황을 경험해보기 위해서 기획되었다. 특히, MSA 설계와 비동기 처리 방식을 경험해보고 마지막에는 부하테스트까지 활용해서 시스템의 병목을 파악해볼 수 있었다는 점에서 의미가 있었다.팀장으로서 프로젝트를 진행하면서 협업의 중요성을 체감할 수 있었고 이번 프로젝트에서 얻은 경험은 이후 프로젝트와 실제 서비스 개발에 있어서 좋은 밑거름이 될 것이라고 확신한다.

[DevOps Engineer]

인프라 아키텍처 구축
IaC 기반 인프라 자동화
모니터링 시스템 구축
시스템 보안 및 취약점 설계
설계 단계에서 논의된 구조를 직접 구현하면서, 예상과 다르게 동작하는 부분들을 하나씩 잡아나갔습니다. Terraform과 Ansible로 인프라를 코드화했는데, 처음엔 각각 따로 쓰다가 Terraform Output을 Ansible 인벤토리로 연결하면서 도구 간 연동이 왜 중요한지 느꼈습니다. 모니터링은 Prometheus/Grafana/Loki로 구성하고 Alertmanager를 Discord와 연동했는데, 실제로 Pod 재시작 알림을 받고 바로 대응했을 때 구축해둔 보람을 느꼈습니다. CI/CD는 GitHub Actions에 Semgrep·Trivy를 연동해 보안 검사를 자동화했고, CVE가 탐지됐을 때 직접 의존성을 수정하면서 자동화의 효과를 체감했습니다. 단순히 도구를 나열해서 쓴 게 아니라, 코드 변경부터 배포까지 전체 흐름이 어떻게 연결되는지 이해하게 된 프로젝트였습니다.

[Backend Developer]

핵심 기능 개발 및 고도화
데이터베이스 구축
API 설계 및 구현
부하 테스트 수행
대규모 트래픽 상황에서도 안정적으로 동작하는 티켓팅 시스템을 설계 및 구현하는 것을 목표로 진행했습니다. 특히 동시성 제어, 실시간 상태 동기화, 장애 상황 등 고려할 점이 많았기에 하나의 정답이 아니라 trade off 중심에서 적절한 선택을 해야 된다는 점을 경험할 수 있었습니다. 한 사례로 좌석 페이지에서 사용자의 출입에 대해 하나씩 조회하는 방식의 정확성과 입장한 사용자의 수를 따로 저장하여 성능을 개선하는 방식 사이에서 고민했습니다. 이때 성능 개선 방식을 사용하되 상한과 하한을 정하여 동시 입장 수를 제한하여 성능 저하와 동시성 문제를 최소화하도록 설계했습니다. 다만 초반에 전체 구조와 우선순위를 충분히 계획하지 못한 채 기능 위주로 개발을 진행하면서, 후반부에 꼭 필요한 기능들을 짧은 시간 안에 몰아서 구현해야 했던 점은 아쉬움으로 남습니다.