대기열 시스템

박태현·2025년 5월 7일

종종 티켓팅 사이트에서 대기열 시스템을 이용하면서, 티켓 오픈 시간과 동시에 적게는 수천 명, 많게는 수만 명의 사용자가 한꺼번에 몰리는 상황을 경험하곤 했습니다.

이때 실시간으로 자신의 대기 번호나 남은 대기자 수를 확인할 수 있었는데, 이렇게 수많은 트래픽을 처리하는 대기열 시스템의 구조와 동작 방식이 문득 궁금해졌고, 직접 한 번 구현해보고자 합니다.

구현 기술


사용 기술

BE : SpringBoot, Spring Webflux, Java

FE : React.js, JavaScript

DB/Cache : MySQL, Redis Sorted Set

Etc : SSE

요구사항


대기열 시스템은 짧은 시간에 대량의 트래픽이 유입되는 상황에서 서버 부하를 안정적으로 관리하기 위해 사용하는 구조입니다.

이 시스템은 서버가 동시에 처리할 수 있는 요청 수를 제한하고, 초과된 요청은 대기열에 저장해 순차적으로 처리함으로써 서버 과부하를 효과적으로 방지합니다.

만약 대기열 시스템이 없다면 갑작스러운 트래픽 폭주로 인해 서버 다운, 응답 지연, 오류 발생 등의 문제가 발생할 수 있습니다.

따라서 특정 시점에 많은 사용자가 몰리는 환경에서는 안정적인 서비스를 제공하기 위해 대기열 시스템이 필요합니다.

트래픽의 유형 3가지

  1. 선형적으로 트래픽이 증가하는 경우

    트래픽이 천천히 증가하므로 서버 확장이나 DB 성능 조정 등으로 대응이 가능합니다.

  2. 트래픽이 반복적으로 늘었다 줄었다 하는 경우

    출퇴근 시간의 대중교통 앱, 식사시간의 배달앱처럼 일정 주기에 따라 트래픽이 변동하는데, 이 경우 자동화된 스케일 인/아웃 기능을 통해 대응할 수 있습니다.

  3. 짧은 시간 내 급격하게 폭증 하는 경우

    티켓팅이나 수강신청과 같은 이벤트에서는 수 초 내에 수십 배의 트래픽이 몰릴 수 있으며, 이는 일반적인 스케일 아웃으로는 대응하기 어렵고, 이 경우 대기열 시스템이 매우 효과적으로 작동합니다.

구조


논블로킹 I/O를 지원하는 WebFlux와 Redis를 활용하여 구현 해볼 예정입니다.

이를 통해 동시에 유입되는 대규모 트래픽 환경에서도 접속자 수를 효과적으로 제어하고 관리할 수 있는 구조를 만들고자 합니다.

기존에는 사용자가 웹 애플리케이션에 직접 접속해 곧바로 타깃 페이지로 이동하여 요청과 응답을 주고받는 방식이었습니다.

하지만 대기열 시스템을 도입하면 사용자가 먼저 대기열 페이지에 진입해 현재 대기 인원이나 예상 대기 시간 등을 확인하게 되며, 자신의 대기 순서가 되었을 때 자동으로 타깃 페이지로 이동합니다.

이러한 구조는 순간적으로 몰리는 트래픽을 완화하여 서버 부하를 줄여줍니다.

대기열에 필요한 기능

  1. 들어오는 요청을 순서대로 저장해야 합니다.

  2. 각 사용자는 대기열에서 자신의 순위가 몇 번인지 알 수 있어야 합니다.

  3. 대기열에 등록된 순서에 따라 요청을 차례대로 처리합니다.

대기열 자료구조로 Redis의 Sorted Set을 사용

접속자 대기열 시스템을 구현하기 위해 고민하던 중, 처음에는 Kafka, RabbitMQ, AWS SQS처럼 대규모 메시지를 빠르고 안정적으로 처리하는데 특화된 메시지 큐 시스템들이 떠올랐습니다.

하지만, 이러한 메시지 큐는 메시지를 순차적으로 처리하는 데에는 강점이 있으나, 특정 메시지가 큐에서 몇 번째 위치에 있는지 확인할 수 없고, 사용자가 실시간으로 자신의 대기 순서를 조회할 수 있는 구조를 제공하지 않는다는 한계가 있습니다.

따라서, 제가 만들고자 하는 대기열 시스템에는 적합하지 않다고 판단했습니다.

최종적으로 선택한 기술은 Redis의 Sorted Set 자료구조입니다. Sorted Set은 각 사용자의 요청 시각을 score 값으로 저장하면 그 값을 기준으로 자동 정렬해주기 때문에, 사용자의 현재 순위나 남은 대기자 수를 매우 빠르게 계산할 수 있습니다.

이러한 특성 덕분에 대기열 시스템에 필요한 핵심 기능들을 구현할 수 있어 가장 적합한 선택이라고 생각했습니다.

profile
꾸준하게

0개의 댓글