Quantcast
Channel: pastpresentproject
Viewing all articles
Browse latest Browse all 449

잭팟 당첨 알림 브로드캐스팅을 위한 Pub/Sub 패턴 아키텍처

$
0
0

Pub/Sub 패턴의 기본 개념과 작동 원리

Pub/Sub 패턴은 발행자(Publisher)와 구독자(Subscriber)라는 두 주요 구성 요소로 이루어진 메시징 패턴입니다. 발행자는 특정 주제(Topic)에 메시지를 게시하기만 하며, 그 메시지를 받을 구독자가 누구인지 알 필요가 없습니다. 반대로 구독자는 자신이 관심 있는 주제를 구독하고, 해당 주제에 새로운 메시지가 발행되면 이를 비동기적으로 수신합니다. 이 패턴의 핵심은 발행자와 구독자 사이의 완전한 분리(Decoupling)에 있습니다. 시스템의 한 부분이 다른 부분의 상태를 직접 조회하거나 호출하지 않고도 이벤트를 통해 정보를 전파할 수 있습니다. 이는 특히 실시간 알림이나 상태 변경 브로드캐스팅과 같은 시나리오에서 강력한 유연성을 제공합니다.

잭팟 당첨 알림과 같은 이벤트는 전형적인 발행-구독 모델에 적합한 사례입니다. 당첨 결과 처리 시스템은 단 한 번의 ‘발행’ 동작으로 이벤트를 발생시킵니다. 이 메시지를 구체적으로 누가, 어떻게 처리할지는 발행자의 관심사가 아닙니다. 수천 명의 실시간 사용자 인터페이스, 관리자 대시보드, 데이터 분석 큐, 외부 로깅 시스템 등 다양한 구독자들이 각자의 필요에 따라 이 동일한 이벤트를 구독하고 독립적으로 처리할 수 있습니다. 이렇게 구성하면 중앙 시스템의 부하를 분산시키고, 새로운 알림 채널을 추가하거나 변경할 때 기존 발행 로직을 수정할 필요가 없어집니다.

이 패턴을 구현하기 위한 기술적 기반은 다양하게 존재합니다. Redis의 Pub/Sub 기능, Apache Kafka, RabbitMQ, Google Cloud Pub/Sub, AWS SNS/SQS 조합 등이 널리 사용되는 솔루션입니다. 각 솔루션은 지속성, 전달 보장, 확장성, 처리량 측면에서 다른 특성을 지니므로, 잭팟 알림의 규모, 실시간성 요구사항, 시스템 환경에 맞게 선택해야 합니다. 예를 들어, 매우 빠른 실시간 전달이 최우선이라면 Redis Pub/Sub을, 대량의 메시지에 대한 높은 신뢰성과 내구성이 필요하다면 Kafka나 RabbitMQ를 고려할 수 있습니다.

중앙의 메시지 브로커에 여러 발신자가 이벤트 화살표를 보내고, 여러 수신자가 화살표를 받아가는 구성의 분리된 통신 시스템을 표현한 다

잭팟 알림 브로드캐스팅을 위한 아키텍처 설계

잭팟 당첨 알림을 위한 Pub/Sub 아키텍처를 설계할 때는 몇 가지 핵심 계층을 고려해야 합니다. 첫 번째는 이벤트 발행 계층입니다. 게임 서버나 당첨 처리 모듈은 내부 로직을 완료한 후, ‘jackpot.won’과 같은 명확한 주제(Topic)로 당첨 정보를 담은 메시지를 발행합니다. 이 메시지에는 당첨 게임 ID, 당첨 금액, 당첨 시간, 익명화된 사용자 식별자 등이 포함됩니다. 발행 계층의 역할은 오로지 이벤트의 생성과 발행에만 집중하며, 메시지 브로커의 성공적인 수신 확인만을 기대합니다.

두 번째는 메시지 브로커 계층입니다. 이 계층은 발행된 메시지를 수신하고, 해당 주제를 구독하고 있는 모든 구독자에게 메시지를 전달하는 중개자 역할을 합니다. 브로커는 구독자 목록을 관리하고, 구독자의 연결 상태나 처리 속도와 무관하게 발행된 모든 메시지를 안정적으로 큐에 보관합니다. 고가용성과 확장성을 위해 브로커 클러스터를 구성하는 것이 일반적입니다. 이 계층의 안정성이 전체 알림 시스템의 신뢰성을 결정한다고 해도 과언이 아닙니다.

세 번째는 구독자 및 알림 전달 계층입니다. 이 계층에는 다양한 서비스가 존재할 수 있습니다. 실시간 웹소켓 서버는 ‘jackpot.won’ 주제를 구독하여 연결된 모든 클라이언트나 특정 사용자 세션에게 푸시 알림을 즉시 전송합니다. 모바일 푸시 알림 서비스는 해당 메시지를 받아 APNs 또는 FCM을 통해 기기로 알림을 발송합니다. 데이터베이스는 당첨 기록을 영구 저장하고, 관리자 콘솔은 실시간 대시보드에 당첨 현황을 반영합니다. 각 구독자는 완전히 독립적으로 개발, 배포, 확장될 수 있습니다.

이벤트 발행의 신뢰성과 데이터 무결성

잭팟 당첨 이벤트는 금전적 가치와 직접 연관되어 있기 때문에 발행의 신뢰성과 데이터 무결성이 가장 중요합니다. 발행 로직은 반드시 당첨 처리의 원자성(Atomicity) 내에서 실행되어야 합니다. 즉, 데이터베이스에 당첨 기록이 커밋되는 것과 메시지 브로커로의 발행이 하나의 트랜잭션으로 처리되거나, 최소한 보상적 트랜잭션(Compensating Transaction)을 통해 일관성을 유지할 수 있어야 합니다. 메시지 브로커로의 발행이 실패할 경우를 대비한 재시도 메커니즘도 필수적입니다.

발행되는 메시지의 형식도 표준화되어야 합니다. JSON 형식이 널리 사용되며, 메시지 스키마를 명확히 정의하여 모든 구독자가 동일한 구조의 데이터를 해석할 수 있도록 합니다. 버전 관리도 고려해야 할 사항입니다. ‘jackpot.won.v1’과 같이 주제나 메시지에 버전을 포함시켜, 향후 필드가 추가되거나 변경되더라도 하위 호환성을 유지하면서 새로운 구독자가 업데이트된 형식을 사용할 수 있게 합니다.

메시지 브로커의 선택과 구성

브로커 선택은 트래픽 패턴에 따라 결정됩니다. 잭팟 알림은 비교적 빈도가 낮지만 매우 중요한 메시지이므로, 메시지의 영속적 저장과 최소 한 번 이상의 전달 보장(At-least-once delivery)이 가능한 브로커가 적합합니다. Apache Kafka는 높은 처리량과 내구성을 제공하며, 파티셔닝을 통해 수평 확장이 용이합니다. RabbitMQ는 유연한 라우팅과 다양한 프로토콜 지원으로 복잡한 구독 패턴을 구현할 때 강점이 있습니다. 클라우드 환경이라면 관리형 서비스인 Google Cloud Pub/Sub이나 Amazon SNS를 사용하면 인프라 관리 부담을 줄일 수 있습니다.

브로커 구성 시 주제(Topic)를 어떻게 설계할지도 중요합니다. 모든 잭팟 알림을 하나의 주제로 묶을지, 게임 종류별(‘topic.slots.jackpot’, ‘topic.blackjack.jackpot’)이나 규모별로 세분화할지 결정해야 합니다. 세분화하면 구독자가 필요한 메시지만 선택적으로 받을 수 있어 네트워크 트래픽과 처리 부하를 줄일 수 있습니다. 또한, 브로커의 모니터링과 알림 설정을 통해 메시지 지연이나 큐 길이 이상을 빠르게 감지할 수 있도록 해야 합니다.

구독자 서비스의 확장성과 장애 격리

구독자 서비스는 각자의 책임 영역에 맞게 설계됩니다. 웹소켓 알림 서비스는 수많은 동시 연결을 관리해야 하므로 이벤트 기반의 비동기 아키텍처를 채택하고, 필요에 따라 여러 인스턴스로 쉽게 확장할 수 있어야 합니다. 모바일 푸시 서비스는 외부 플랫폼(Apple, Google)의 API 호출 제한과 지연 시간을 고려하여 배치 처리나 큐잉 방식을 도입할 수 있습니다. 핵심 원리는 한 구독자의 장애나 처리 지연이 다른 구독자나 발행자에게 영향을 미치지 않아야 한다는 점입니다.

이를 위해 각 구독자는 자신의 처리 속도에 맞게 메시지를 소비해야 합니다. 브로커가 푸시 방식이 아니라면, 구독자가 풀(Pull) 방식으로 메시지를 가져와 처리한 후 명시적으로 승인(Acknowledgment)을 보내는 패턴이 안정적입니다. 메시지 처리 중 오류가 발생하면 해당 메시지를 데드 레터 큐(Dead Letter Queue)로 이동시켜 나중에 검토하고, 정상 메시지의 흐름은 멈추지 않도록 해야 합니다.

실시간 알림 전달을 위한 웹소켓 연동

사용자에게 가장 직접적인 잭팟 당첨 알림은 웹이나 앱 내의 실시간 푸시를 통해 이루어집니다. 이를 위해 웹소켓 서버는 메시지 브로커의 핵심 구독자 중 하나입니다. 웹소켓 서버는 시작 시 ‘jackpot.won’ 주제를 구독합니다. 브로커로부터 당첨 메시지를 수신하면, 웹소켓 서버는 내부적으로 관리하는 연결된 클라이언트 목록을 확인합니다. 알림은 모든 접속자에게 브로드캐스트될 수도 있고, 당첨자本人에게만 전송될 수도 있으며, 이는 메시지에 포함된 식별자 정보를 통해 결정됩니다.

웹소켓 서버의 확장성을 보장하기 위해 여러 인스턴스를 운영할 경우, 세션 공유 문제를 해결해야 합니다. 사용자가 특정 웹소켓 서버 인스턴스에 연결되어 있을 때, 당첨 메시지가 다른 인스턴스로 전달되면 알림을 받을 수 없기 때문입니다, 이를 해결하기 위해 redis pub/sub이나 클러스터링 메시지를 통해 인스턴스 간에 메시지를 중계하거나, 사용자-인스턴스 매핑 정보를 공유 저장소에 저장하고 메시지를 적절한 인스턴스로 라우팅하는 방법을 사용할 수 있습니다.

웹소켓 연결이 불안정하거나 일시적으로 끊길 수 있다는 점도 고려해야 합니다. 이를 대비하여 클라이언트는 재연결 로직을 구현하고, 서버는 중요한 알림 메시지에 일정 시간 동안의 임시 캐시를 적용하여 재연결 후 놓친 알림을 전달받을 수 있는 메커니즘을 추가할 수 있습니다. 이 모든 과정은 Pub/Sub 패턴 덕분에 게임 서버나 당첨 처리 로직과는 완전히 분리되어 운영됩니다.

중앙의 대형 당첨 알림 시스템이 네트워크로 연결된 여러 화면과 기기에 메시지를 전송하는 구성도입니다.

다중 채널 알림 전략

웹소켓 알림 외에도 사용자 참여를 높이기 위해 다중 채널 알림을 구성할 수 있습니다. 모바일 앱 푸시, SMS, 이메일 등이 추가 채널이 될 수 있습니다. Pub/Sub 아키텍처에서는 이러한 추가가 매우 간단합니다. 각 채널을 담당하는 새로운 구독자 서비스를 개발하여 동일한 ‘jackpot.won’ 주제를 구독하도록 하기만 하면 됩니다. 예를 들어, ‘푸시 알림 서비스’는 메시지를 받아 FCM/APNs 포맷으로 변환하여 전송하고, ‘알림 집계 서비스’는 사용자의 알림 수신 내역을 데이터베이스에 기록합니다.

이때, 사용자가 각 채널에 대한 수신 동의를 관리하고 있다면, 구독자 서비스는 메시지를 받은 후 사용자 설정을 조회하여 실제 전송 여부를 결정하는 로직을 추가해야 합니다. 이는 구독자 서비스의 책임 영역으로, 발행자는 이러한 세부 사항을 전혀 알지 못합니다. 이렇게 함으로써 알림 정책이 변경되거나 새로운 채널이 추가되어도 기존 시스템의 다른 부분에는 변경이 발생하지 않습니다.

모니터링과 운영 고려사항

잭팟 알림 시스템의 건강 상태를 모니터링하는 것은 필수적입니다. 주요 모니터링 지표로는 메시지 발행부터 각 구독자의 처리 완료까지의 종단 간 지연 시간, 초당 발행/소비 메시지 수, 구독자별 미처리 메시지 백로그 크기, 구독자 서비스의 에러율 등이 있습니다. 이러한 지표를 통해 시스템의 병목 현상을 신속히 발견하고 확장 여부를 판단할 수 있습니다.

운영 측면에서 중요한 것은 장애 복구 절차입니다. 예를 들어, 웹소켓 알림 서비스가 다운된 시간 동안 브로커에 쌓인 메시지를 서비스 재개 후 어떻게 처리할지 전략이 필요합니다. 일반적으로 구독자는 마지막으로 승인한 메시지의 오프셋부터 메시지를 다시 가져와 처리합니다. 또한, 시스템 전체에 영향을 주지 않으면서 새로운 구독자 서비스를 테스트하기 위해, 테스트용 주제를 만들거나 프로덕션 주제의 메시지를 복제하여 테스트 환경으로 전달하는 방법도 활용됩니다.

아키텍처의 장점과 구현 시 주의점

Pub/Sub 패턴을 기반으로 한 잭팟 알림 아키텍처는 뚜렷한 장점을 제공합니다. 첫째, 시스템 간 결합도가 낮아 개별 컴포넌트의 개발, 배포, 확장이 자유롭습니다. 둘째, 이벤트 중심의 설계로 새로운 비즈니스 요구사항(예: 새로운 알림 채널 추가)에 빠르게 대응할 수 있습니다. 셋째, 메시지 브로커가 버퍼 역할을 하여 순간적인 트래픽 급증을 완화하고, 구독자의 처리 속도 차이를 자연스럽게 흡수합니다. 이는 게임 서버의 안정성에 직접적인 기여를 합니다.

하지만 구현 시 몇 가지 주의점이 있습니다. 첫째, ‘최소 한 번’ 이상의 전달 보장은 메시지 중복 수신의 가능성을 의미합니다. 구독자 서비스는 멱등성(Idempotency)을 보장하는 설계가 되어야 합니다. 동일한 당첨 ID를 가진 메시지를 두 번 처리하더라도 알림이 중복 발송되거나 기록이 중복 생성되지 않도록 해야 합니다. 둘째, 메시지의 순서 보장이 필요한지 검토해야 합니다. 대부분의 잭팟 알림은 독립적이지만, 특정 게임의 상태 변화 알림 시리즈라면 순서가 중요할 수 있습니다. 이 경우 주제의 파티션을 활용하거나 순서 보장을 지원하는 브로커를 선택해야 합니다.

마지막으로 보안 측면에서, 메시지 브로커와 구독자 간의 통신, 그리고 발행되는 메시지 자체에 대한 보안을 고려해야 합니다. 인증과 암호화를 적용하여 민감한 당첨 정보가 무단으로 접근되거나 변조되지 않도록 해야 합니다. 또한, 내부 시스템 이벤트라도 필요 이상의 개인 식별 정보를 포함하지 않도록 데이터를 익명화하거나 최소화하는 원칙을 적용하는 것이 좋습니다.

FAQ: 잭팟 알림 Pub/Sub 아키텍처에 대한 궁금증

Q1: 한 번 발행된 잭팟 당첨 메시지를 나중에 새로 개발된 서비스가 과거 데이터로 받아 처리할 수 있나요?
A: 이는 선택한 메시지 브로커의 기능에 달려 있습니다. Apache Kafka처럼 메시지를 일정 기간 디스크에 보관하는 브로커를 사용하면, 새로운 서비스가 특정 과거 시점부터 메시지를 소비하는 ‘리플레이’가 가능합니다. 반면, Redis Pub/Sub처럼 발행 당시의 구독자에게만 즉시 전달하는 브로커는 이 기능을 지원하지 않습니다. 데이터 분석이나 백업 목적이라면 메시지를 영구 저장소에 저장하는 별도의 구독자를 두는 것이 일반적입니다.

Q2: 사용자가 알림을 받지 못했다고 문의할 경우, 문제 지점을 어떻게 추적하나요?
A: 종단 간(End-to-End) 추적을 활용해야 합니다. 알림 요청 시점에 생성된 고유한 추적 ID(예: trace_id)를 데이터베이스의 발송 기록, 외부 발송 서비스(FCM/APNS) 호출 로그, 그리고 최종적으로 발송 성공/실패 응답 로그에 걸쳐 확인하여, 알림이 어느 단계에서 누락되거나 지연되었는지 정확히 파악할 수 있습니다.


Viewing all articles
Browse latest Browse all 449

Trending Articles