CGV 예매 대기열 시스템
개발계 AWS 네트워크(Terraform)와 Redis, Kinesis 대기열 백엔드(Spring Boot)
CJ 올리브네트웍스 클라우드웨이브 6기(2025.06 - 09) 5인, 3주 팀 프로젝트. 2024년 한국시리즈 극장 생중계 예매 대기 16만 명 사례를 기준으로, 몰리는 수요를 백엔드 처리량에 맞춰 조절하는 대기열을 구현했습니다. 담당은 AWS 개발계 네트워크 계층(Terraform) 과 대기열 백엔드(Spring Boot)입니다.
개발계 구조

설계 결정
네트워크 계층
| 항목 | 선택 | 이유 |
|---|---|---|
| 서브넷 인터넷 경로 | Public은 양방향, EKS는 나가는 것만, GitLab과 DB는 없음 | 소스 저장소와 DB가 같은 VPC에 있어, 서브넷마다 필요한 만큼만 개방 |
| ECR 트래픽 | ecr.api와 ecr.dkr 엔드포인트를 서브넷마다 | 하나만 두면 인증은 되는데 pull이 NAT로 나감. 인터페이스 엔드포인트는 서브넷 단위 ENI |
| NAT Gateway | 2a 하나만 두고 2c 라우트도 여기로 | 시간당 요금이 절반. 개발 환경이라 2a 장애 시 2c 아웃바운드 단절은 감수 |
| 원격 state | S3와 DynamoDB, 별도 디렉터리 | state를 담는 S3와 DynamoDB를 같은 코드로 만들면 그 코드가 자기 state를 먼저 필요로 함 |
대기열
| 항목 | 선택 | 이유 |
|---|---|---|
| 대기열 상태 | Redis Sorted Set 둘. waiting은 상한 없음, active는 Pod 수 기반 정원 | score가 요청 시각이라 도착 순서가 유지되고 순위 조회도 빠름 |
| 입장 처리 | 2초 주기 프로세서로 빈 자리만큼 앞에서부터 | 정원이 비는 즉시가 아니라 주기로 입장시켜야 Redis 왕복이 요청마다 늘지 않음 |
| 입장 통지 | Kinesis에 WebSocket과 폴링 이중 | 입장 통지를 놓치면 예매 화면에 못 들어감. 24시간 재처리 보존, 연결이 끊겨도 폴링이 수신 |
트러블슈팅
| 증상 | 원인 | 조치 |
|---|---|---|
| Consumer 폴링에 Kinesis 읽기 한도 초과 오류 반복 | 샤드 1개(초당 5회)를 Pod 6개가 폴링하는데 0번 샤드만 읽어 증설로도 해소되지 않음 | 샤드를 2개로 증설하고 Pod 순번으로 분배. Pod 10개가 초당 1회면 초당 10회, 샤드당 한도가 5회라 2개 |
| Pod의 Kinesis 접근 거부. IRSA가 아닌 EC2 노드 역할로 접근 중 | ServiceAccount annotation과 신뢰 관계는 정상. 앱에 AWS 연동 의존성이 없어 IRSA 환경변수를 인식하지 못함 | spring-cloud-aws-starter 의존성 추가 |
| 인증서를 ACM에 올리고 Client VPN 연결 시 TLS 핸드셰이크 실패 | 서버 인증서 CN이 server 같은 비FQDN이라 ACM이 도메인을 인식하지 못함 | Easy-RSA PKI 재구성, FQDN CN으로 재발급 |
destroy 뒤 apply 하면 GitLab 인스턴스에 빈 볼륨 | root_block_device 인라인이라 인스턴스 교체 시 새 볼륨이 생성됨. 기존 볼륨은 남았지만 연결되지 않음 | 볼륨을 별도 자원으로 분리해 기존 볼륨을 import 후 연결 |
결과
- 개발계 네트워크 계층 코드화: VPC, 서브넷 6개, 라우트 테이블 4개, 보안그룹 5개, 엔드포인트 5개, GitLab EC2
- 정원 초과 요청의 대기열 전환 확인: UUID 10,000명 투입 시 200(즉시 입장)과 202(대기 등록)로 분기, 부하 중 HPA 확장을 ArgoCD에서 확인
- 단계별 병목 해소: 100명에서 1,000명, 10,000명으로 올리며 Redis 풀 10 → 20, Kinesis 샤드 1 → 2
한계
- CI/CD와 EKS 구축, 배포계는 팀원 담당: 파이프라인과 클러스터를 직접 구축하지 않았고 부하는 개발계 동작 확인까지. 클러스터 구축은 홈랩, EKS 구축은 클라우드에서 보완
- Kinesis와 WebSocket 기능 대부분 미사용: 단일 소비자라 Fan-out과 재처리가 불필요했고, 단방향 알림인데 양방향 연결을 유지
- Client VPN을 dev 편의로 퍼블릭 서브넷 접근으로 전환: 코드에 GitLab 보안그룹 인바운드
0.0.0.0/0이 남음
기술 스택
Terraform, AWS(VPC, VPC Endpoint, Client VPN, EKS, Kinesis, ECR, IRSA), Java 17, Spring Boot 3.3, JPA, Redis(Sorted Set), WebSocket(STOMP), MySQL