한정 좌석 이벤트에서 동시에 몰리는 예약 요청을 비동기적으로 처리하는 티케팅 웹 서비스입니다.
사용자는 요청 시 즉시 job_id를 발급받고, 백엔드에서 스레드 기반 워커가 실제 예약(좌석 배정)을 처리합니다.
| 프로그램 | 최소 버전 | 설치 링크 |
|---|---|---|
| Docker Desktop | 4.0+ | Docker 공식 사이트 |
| Git | 2.0+ | Git 공식 사이트 |
docker --version
docker-compose --version# PowerShell 또는 명령 프롬프트에서
docker --version
docker-compose --versionDocker Desktop이 실행되어 있어야 합니다 - 시스템 트레이에 Docker 아이콘 확인
# 프로젝트 클론
git clone <repository-url>
cd ticketing_test
# 모든 서비스 시작
docker-compose up -d --build
# 서비스 상태 확인
docker-compose ps# API 서버 확인
curl http://localhost:8000
# 예상 응답
{
"message": "Asynchronous Ticketing Service API",
"version": "1.0.0"
}docker-compose down- 티켓 예약 요청: 즉시 job_id 반환, Redis 큐에서 비동기 처리
- Job 상태 조회: 예약 진행 상황 및 결과 확인
- 처리 통계: 현재 처리 중인 작업 개수 조회
- 이벤트 관리: 이벤트 생성 및 좌석 현황 조회
- Job ID는 순차적으로 증가
- Job은 순서대로 실행될 필요 없음
- 좌석 중복 배정 방지
- Job 상태 영속 저장으로 재조회 보장
- FastAPI: REST API 서버
- PostgreSQL: 영속 데이터 저장 (이벤트, 좌석, Job 상태)
- Redis: Job 큐 + 시퀀스 관리 + 통계
- Worker Threads: 백그라운드에서 실제 좌석 할당 처리
- Docker Compose: 통합 실행 환경
- Thread 사용:
ThreadPoolExecutor로 CPU 코어 기반 스레드 풀 관리 - 순차 Job ID: Redis
INCR로 job_id 발급 - 데이터 정합성: PostgreSQL 트랜잭션 + 낙관적 락
- 시스템 부하 제어: 제한된 스레드 + Redis 큐 버퍼링
curl -X POST "http://localhost:8000/events" \
-H "Content-Type: application/json" \
-d '{"name": "Fan Meet", "total_seats": 100}'curl -X POST "http://localhost:8000/events/1/reserve" \
-H "Content-Type: application/json" \
-d '{"request_id": "req-001", "user_id": "user123", "quantity": 2}'curl "http://localhost:8000/jobs/1024"curl "http://localhost:8000/stats/processing_count"curl "http://localhost:8000/events/1/status"- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
# 모든 테스트 실행
docker-compose exec app pytest tests/ -v
# 단위 테스트만
docker-compose exec app pytest tests/test_unit.py -v
# 통합 테스트만
docker-compose exec app pytest tests/test_main.py -v# 가상환경 생성 및 활성화
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 의존성 설치
pip install -r requirements.txt
# 테스트 실행 (서비스 실행 필요)
python -m pytest tests/ -v- 브라우저에서 접속: http://localhost:8089
- 단계별 부하 테스트:
| 단계 | 사용자 수 | Spawn Rate | 목적 |
|---|---|---|---|
| 🟢 1단계 | 5명 | 1/초 | 기본 동작 확인 |
| 🟡 2단계 | 20명 | 3/초 | 실제 사용량 시뮬레이션 |
| 🟠 3단계 | 50명 | 5/초 | 성능 한계 확인 |
| 🔴 4단계 | 100명 | 10/초 | 스트레스 테스트 |
# 테스트 시작 (20명 사용자)
curl -X POST "http://localhost:8089/swarm" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "user_count=20&spawn_rate=3"
# 통계 확인
curl "http://localhost:8089/stats/requests" | python3 -m json.tool
# 테스트 중지
curl -X GET "http://localhost:8089/stop"- 100명 동시 사용자 처리 가능
- 325.7 RPS 달성 (예상치 400% 초과)
- 0% 실패율 - 37,189개 요청 완벽 처리
- 3.9ms 평균 응답시간
ticketing_test/
├── app/ # FastAPI 애플리케이션
│ ├── api/ # API 라우터들
│ ├── core/ # 핵심 설정 및 인프라
│ ├── models/ # SQLAlchemy ORM 모델
│ ├── schemas/ # Pydantic 스키마
│ ├── services/ # 비즈니스 로직 레이어
│ └── main.py # FastAPI 앱 엔트리포인트
├── worker/ # 백그라운드 워커
│ ├── worker.py # 티켓 예약 처리 워커
│ └── runner.py # 워커 프로세스 실행기
├── shared/ # 공유 컴포넌트
│ └── redis_client.py # Redis 클라이언트 및 큐 관리
├── tests/ # 테스트 파일
├── load_test/ # 부하 테스트
├── docker-compose.yml # Docker Compose 서비스 정의
├── Dockerfile # 앱 컨테이너 이미지 빌드
└── requirements.txt # Python 의존성
# 사용 중인 포트 확인 (macOS/Linux)
lsof -i :8000
# Windows
netstat -ano | findstr :8000# 캐시 없이 재빌드
docker-compose build --no-cache
# 전체 재시작
docker-compose down -v
docker-compose up -d --build# 상세 오류 확인
docker-compose exec app pytest tests/ -v -s --tb=long
# 로그 확인
docker-compose logs app worker# 서비스 상태 확인
docker-compose ps
# 앱 로그 확인
docker-compose logs app --tail=50
# 헬스체크
curl -I http://localhost:8000/- M1/M2 칩에서는 Docker 이미지 플랫폼 호환성 확인 필요
- WSL2 백엔드 사용 권장
- PowerShell 실행 정책 확인
- Docker 사용자 권한 설정:
sudo usermod -aG docker $USER
# 서비스 시작
docker-compose up -d
# 서비스 중지
docker-compose down
# 로그 확인
docker-compose logs -f app worker
# 데이터베이스 접속
docker-compose exec postgres psql -U user -d ticketing_db
# Redis 접속
docker-compose exec redis redis-cli- 수평 확장: Celery, Redis Streams, Kafka로 마이그레이션 가능
- 모니터링: Prometheus, Grafana 연동
- 로드밸런싱: 다중 인스턴스 배포시 Redis를 통한 상태 공유
- 캐싱: 자주 조회되는 이벤트 정보 캐싱
이 프로젝트는 교육 목적으로 제작된 샘플 애플리케이션입니다.