바이브코딩을 하다 보면 한 번쯤 이런 상상을 합니다.
“갑자기 사용자가 몰려서 서버가 터지면 어떡하지?”
물론 대부분의 개인 서비스에서는 그런 일이 쉽게 생기지 않습니다. 하지만 운 좋게 글이 퍼지거나 커뮤니티에 소개되면, 작은 서버가 순간 트래픽을 견디지 못할 수도 있죠.
그렇다고 오토스케일링을 무제한으로 열어두면 서버 대신 청구서가 터질 수 있습니다.
이럴 때 사용할 수 있는 방법이 가상 대기실입니다.
사용자 접속
→ 현재 입장 인원 확인
→ 자리가 있으면 입장
→ 정원이 차면 대기번호 발급
→ 순서가 되면 입장 토큰 발급
Cloudflare의 정식 Waiting Room은 편리하지만 개인 프로젝트에서 부담스러울 수 있습니다. 대신 Cloudflare Workers와 Durable Objects를 이용하면 작은 규모의 대기실을 무료 플랜에서도 직접 구현할 수 있습니다.
현재 Durable Objects는 Workers Free 플랜에서도 사용할 수 있으며, 무료 플랜에서는 SQLite 저장 방식을 사용합니다. 무료 한도를 초과하면 추가 요금이 자동으로 청구되는 것이 아니라 해당 작업이 제한되거나 실패하는 방식이라 비용 통제 측면에서도 비교적 안전합니다.
왜 Durable Objects가 필요할까요?
일반적인 Worker만 사용하면 여러 사용자가 동시에 접속했을 때 정확한 순서를 관리하기 어렵습니다.
예를 들어 100명이 동시에 들어오면 다음 정보를 한곳에서 안전하게 관리해야 합니다.
- 현재 입장한 사용자 수
- 대기 중인 사용자 목록
- 각 사용자의 대기번호
- 입장 토큰의 발급 여부
- 토큰 만료 시간
- 사용자가 나갔을 때 생긴 빈자리
Durable Objects는 여러 요청이 공유해야 하는 상태를 한곳에서 조정하는 데 적합합니다. 실시간 채팅이나 협업 서비스처럼 여러 사용자의 접속 상태를 관리하는 용도로도 사용됩니다.
최소 기능은 이 정도면 됩니다
처음부터 놀이공원처럼 정교한 대기 시스템을 만들 필요는 없습니다.
1. 입장 정원 설정
최대 동시 입장 인원: 100명
현재 입장 인원이 100명보다 적으면 바로 입장시키고, 정원이 차면 대기 페이지를 보여줍니다.
2. 대기번호 발급
대기 사용자에게 임의의 토큰과 순번을 발급합니다.
현재 대기번호: 37번
앞에 남은 인원: 12명
새로고침할 때마다 줄의 마지막으로 밀려나지 않도록 토큰을 쿠키에 저장합니다.
3. 입장 토큰 발급
자리가 생기면 대기 중인 사용자에게 일정 시간 동안 유효한 입장 토큰을 발급합니다.
입장 가능
토큰 유효시간: 20분
토큰이 없는 사용자는 실제 서비스로 바로 접근하지 못하게 Worker에서 검사합니다.
4. 대기 상태 갱신
가장 간단한 방법은 대기 페이지에서 5~10초마다 현재 순번을 다시 확인하는 것입니다.
조금 더 실시간으로 만들고 싶다면 WebSocket을 사용할 수 있습니다. Durable Objects는 WebSocket 연결을 관리할 수 있고, Hibernation API를 사용하면 연결을 유지하면서 유휴 시간의 리소스 사용을 줄일 수 있습니다.
전체 구조는 간단합니다
방문자
↓
Cloudflare Worker
↓
Durable Object
├─ 정원 여유 → 입장 토큰 발급 → 실제 사이트
└─ 정원 초과 → 대기번호 발급 → 대기 페이지
실제 서버는 입장 토큰을 가진 사용자 요청만 받습니다.
덕분에 서버가 처리할 수 있는 수준으로 접속자를 제한하면서, 오토스케일링 비용도 일정 범위 안에서 통제할 수 있습니다.
정말 무료일까요?
작은 개인 서비스라면 무료로 시작할 수 있습니다.
다만 무료이지만 무제한은 아닙니다.
Workers와 Durable Objects의 요청, 실행 시간, 저장 공간에는 무료 한도가 있습니다. 무료 플랜에서 한도를 넘으면 해당 작업이 실패할 수 있으므로, 대기실 자체도 무한 트래픽을 받아주는 방패는 아닙니다.
그래서 다음 준비를 함께 해두는 편이 좋습니다.
- 정적 대기 안내 페이지 준비
- 대기 상태 확인 주기를 너무 짧게 설정하지 않기
- 입장 토큰 만료 시간 설정
- 봇과 새로고침 공격 방지
- 서버 사용량과 오류 알림 설정
- 관리자용 긴급 입장 중단 기능 추가
특히 1초마다 순번을 확인하게 만들면 방문자가 많을 때 대기실 자체가 엄청난 요청을 발생시킵니다. 초기에는 5~10초 간격의 폴링만으로도 충분합니다.
꼭 정확한 순번이 필요할까요?
처음에는 더 단순하게 시작해도 됩니다.
현재 접속자가 많습니다.
잠시 후 자동으로 다시 연결합니다.
이 화면만 보여주고 일정 시간이 지난 뒤 재시도하게 해도 서버 보호 효과는 있습니다.
서비스가 실제로 성장한 뒤 다음 기능을 하나씩 추가하면 됩니다.
- 정확한 대기번호
- 예상 대기시간
- 실시간 순번 갱신
- 입장 토큰
- 우선 입장
- 예약 이벤트
처음부터 완벽한 시스템을 만들기보다 서버가 감당할 수 있는 사용자만 들여보내는 것이 먼저입니다.
결국 핵심은 트래픽을 무한히 받아내는 것이 아닙니다.
서버가 터지지 않을 만큼만 입장시키고, 비용이 감당 가능한 범위를 넘지 않게 통제하는 것.
Cloudflare Workers와 Durable Objects를 이용하면 개인 프로젝트도 이 구조를 무료로 실험해볼 수 있습니다. 다만 실제 결제나 중요한 업무 서비스를 운영한다면 토큰 위조 방지, 장애 복구, 중복 입장 처리까지 충분히 검증한 뒤 적용하는 것이 좋습니다.
안정적 라이브 서비스 정말 중요하죠. 사용자 몰려서 터지면 어떻하지 누구나 한 번쯤 하는 상상인거 같아요 대응책까지 같이 공부하다 보면 그런 날이 언젠가는 오겠죠? ㅋㅋ 늘 핵심 꿀팁 감사합니다.