공정성 · 안정성 · 신뢰성을 갖춘 MSA 기반 공연 티켓 예매 플랫폼
좋아하는 아티스트의 티켓팅, 정각에 접속했는데 이미 매진된 경험.
First Ticket은 매크로 없이, 정각 접속자 모두가 동등하게 경쟁하는 티켓팅을 목표로 설계되었습니다.
개발 기간: 2026.04.16 ~ 2026.05.20
| ⚖️ 공정성 | 매크로 없이, 정각 접속자 모두가 동등하게 경쟁 |
| 🛡️ 안정성 | 동시 접속 및 요청 폭증 상황에서도 서버 다운 없이 유지 |
| 🔒 신뢰성 | 결제 실패 · 취소 시에도 예매와 좌석이 자동으로 복원 |
- 🎭 공연 조회 및 예매 — 다양한 공연·전시 프로그램을 검색하고, 좌석을 직접 선택하여 예매
- 🎟️ 대기열 입장 — 티켓 오픈 직후 폭주 상황에서도 매크로 없이 정각 접속자가 동등하게 순번을 부여받고 입장
- 💺 좌석 선점 — 마음에 드는 좌석을 일정 시간 동안 임시로 선점하고, 그 안에 결제를 완료해 예매 확정
- 💳 간편 결제 — Toss Payments로 안전하게 결제, 결제 실패·취소 시에도 좌석과 예매가 자동으로 복원
- 🔄 예매 취소 및 환불 — 예매 취소 요청 시 결제 환불부터 좌석 복구까지 자동으로 처리
- 🎤 공연 등록 (주최자) — 주최자가 공연장·스케줄·가격등급을 등록하고 판매 시작 시점 제어
| 영역 | 적용 방식 |
|---|---|
| MSA 아키텍처 | 비즈니스 도메인 단위 서비스 분리 + DDD 적용 |
| 트래픽 처리 안정성 | nGrinder · k6 기반 부하 테스트로 동시 접속 안정 처리 검증 |
| 대기열 시스템 | Redis Sorted Set + Hash + String + Set 기반 대기열로 공정한 선착순 처리 |
| 이벤트 드리븐 통신 | Kafka + Outbox/Inbox 패턴으로 서비스 간 느슨한 결합 및 이벤트 유실 방지 |
| 동시성 제어 | Redisson 분산 락 + Redis TTL 기반 좌석 선점으로 중복 예매 차단 |
| 독립 배포 | AWS ECS Fargate + GitHub Actions 기반 서비스별 독립 CI/CD |
| 관찰성 | Prometheus · Grafana · Zipkin 통합 관찰성 + Slack 임계치 자동 알림 |
| 이름 | 포지션 | 주요 담당 | GitHub |
|---|---|---|---|
| 김하진 | 팀장 | 대기열 도메인, Config Server, ECS 배포 + CI/CD | @rlaxxwls13 |
| 조하은 | 팀원 | 좌석 도메인, 공통 모듈, 모니터링 | @haeun228 |
| 신단비 | 팀원 | 프로그램 도메인, 공연장 도메인 | @sweetRainShin |
| 김두리 | 팀원 | 결제 도메인 | @DDoori |
| 나웅철 | 팀원 | 예매 도메인 | @No-366 |
| 박동진 | 팀원 | 인증·인가, Gateway, Eureka | @straycat405 |
📋 상세 기여 내역 보기
- 대기열 도메인 설계 및 구현 (Redis Sorted Set/Hash/역인덱스, Lua Script 원자성, FIFO tie-breaker, Adaptive Polling)
- Spring Cloud Config Server 구축 (Git + Basic Auth +
{cipher}암호화) - ECS Fargate 배포 인프라 + GitHub Actions OIDC 기반 CI/CD
- 좌석 도메인 (Redisson 분산락, Redis TTL Hold, JDBC batchUpdate, Redis 캐시)
- 공통 모듈 설계 (
common/common-jpa/common-messaging— Outbox/Inbox/멱등 AOP) - Prometheus + Grafana 모니터링 및 Slack 알림 파이프라인
- 프로그램·공연장 도메인 (상태 머신, 가격등급, 시간 겹침 이중 방어 — 비관적 락 + tsrange exclusion)
- Provider 패턴으로 외부 서비스 격리, Outbox 기반 Kafka 발행 설계
- 전체 계층 테스트 코드 (Testcontainers + PostgreSQL), REST Docs 문서화
- 토스페이먼츠 서버 승인 방식 연동, 결제 상태 머신 (
PENDING/FAILED/FINAL_FAILED/SUCCESS/REFUNDED) - 비관적 락 + Idempotency Key + 금액 대조 검증
- Outbox/Inbox 패턴 + DLQ로 결제 이벤트 유실 방지
- 예매 도메인 + Saga Orchestration (
PENDING → PAID → CONFIRMED / CANCEL_REQUESTED → CANCELED) - Redisson
@DistributedLockAOP, 입장 토큰/세션 토큰 분리 검증 - QueryDSL 동적 페이지네이션, 외부 서비스 Feign Client 설계
- 인증 시스템 (Keycloak 26 + JWT 이중 토큰 + Redis Lua CAS Token Rotation + Blacklist)
- API Gateway (
AuthorizationHeaderFilter, Caffeine L1 캐시, Circuit Breaker) - Eureka Server (Caffeine 응답 캐시, 환경별 Self-Preservation 분리)
- HOST 권한 신청/승인 Flow + Partial Unique Index 이중 방어
| 영역 | 기술 |
|---|---|
| Language | Java 21 |
| Framework | Spring Boot 3.5.13 · Spring Cloud 2025.0.2 · Spring Data JPA · QueryDSL |
| 인증 · 보안 | Keycloak 26 · JWT |
| 장애 격리 | Resilience4j (Circuit Breaker · Bulkhead) |
| Database | PostgreSQL · Redis · Redisson |
| DB Migration | Flyway |
| Messaging | Apache Kafka |
| External API | Toss Payments |
| Test | JUnit 5 · Testcontainers · nGrinder · k6 · JMeter |
| Infra | AWS ECS Fargate · AWS EC2 · AWS RDS · AWS ALB · AWS ECR |
| CI / CD | Docker · GitHub Actions |
| Monitoring | Prometheus · Grafana · Zipkin |
| Collaboration | Notion · Slack · GitHub · draw.io |
도메인 단위 MSA. 각 서비스는 독립 배포 · 독립 확장 가능합니다.
| 서비스 | 역할 | 레포 |
|---|---|---|
| 🚪 Gateway Server | 단일 진입점, JWT 서명 검증, Caffeine L1 캐시, Circuit Breaker | Gateway Server |
| 🧭 Eureka Server | 서비스 디스커버리 | Eureka Server |
| ⚙️ Config Server | 중앙 집중 설정 관리 (Git + 암호화) | Config Server |
| 👤 User Service | 회원, 인증(Keycloak), Token Rotation, HOST 권한 | User Service |
| 🏛️ Venue Service | 공연장 · 구역 · 좌석 구조 관리 | Venue Service |
| 🎭 Program Service | 공연/스케줄/가격등급 등록 및 상태 머신 | Program Service |
| 🎟️ Queue Service | Redis 기반 대기열, Adaptive Polling, 예매 입장 토큰 발급 | Queue Service |
| 💺 Booking Service | 좌석 선점(Redisson) + 예매 Saga 오케스트레이터 | Booking Service |
| 💳 Payment Service | Toss Payments 연동, 결제 상태 머신, Outbox | Payment Service |
| 📦 Common Modules | common / common-jpa / common-messaging |
common, common-jpa, common-messaging |
① 대기열 진입 사용자 → Queue Service (Redis Sorted Set + Hash)
② 입장 확인 사용자 폴링 → Queue Service (Adaptive Polling, EntryToken JWT)
③ 예매 세션 생성 사용자 → Booking Service (EntryToken 검증 + 블랙리스트)
④ 좌석 선점 사용자 → Booking Service (Redisson 분산락 + TTL 10분)
⑤ 예매 생성 사용자 → Booking Service (Saga 시작)
⑥ 결제 Booking → Payment Service (Toss PG 서버 승인)
└─ 성공/실패에 따라 Kafka 이벤트 발행 → 보상 트랜잭션
클라이언트
│ Authorization: Bearer <AccessToken>
▼
API Gateway
│ Keycloak 공개키로 서명 검증
│ 검증 성공 → X-User-Id, X-User-Role 헤더 추가
▼
각 마이크로서비스 (헤더 신뢰, 자체 재검증 없음)
주최자가 공연장 → 프로그램(DRAFT) → 스케줄 → 가격 등급을 순차 등록하고
판매 시작(ON_SALE) 시점에 예매 서비스·대기열 서비스가 Kafka로 동기화
주최자 (HOST / ADMIN)
├─ ① 공연장 등록 → Venue Service
│ └─ 구역(SEATED/STANDING/FREE) 포함 시 좌석 자동 생성
│
├─ ② 프로그램 등록 (DRAFT) → Program Service
│ └─ Kafka: program.created → 대기열 초기화
│
├─ ③ 스케줄 등록 → Program Service
│ └─ 비관적 락 + tsrange exclusion 으로 공연장 시간 겹침 차단
│
├─ ④ 가격 등급 등록 → Program Service
│ └─ 좌석 타입별 sectionId 규칙 검증 (Feign)
│
└─ ⑤ 판매 시작 (DRAFT → ON_SALE)
└─ Kafka: schedule.created → 예매 서비스가 BookingSeat 생성
└─ Kafka: program.time.updated → 대기열 서비스가 openAt·closeAt 등록
자세한 실행 가이드는 각 레포의 README 참조
# 1. 인프라 컴포넌트 기동 (PostgreSQL, Redis, Kafka, Keycloak)
docker compose up -d
# 2. 인프라 서비스 (순서 중요)
./gradlew :eureka-server:bootRun # 1순위
./gradlew :config-server:bootRun # 2순위
./gradlew :gateway-server:bootRun # 3순위
# 3. 도메인 서비스
./gradlew :user-service:bootRun
./gradlew :program-service:bootRun
./gradlew :venue-service:bootRun
./gradlew :queue-service:bootRun
./gradlew :booking-service:bootRun
./gradlew :payment-service:bootRun환경 요구사항
- Java 21
- Docker & Docker Compose
- Gradle 8.x
🎫 First Ticket · MSA Ticketing Platform