본문 바로가기
대규모 시스템 설계 기초

대규모 시스템 설계 기초 - 10장

by cafecortado 2025. 4. 12.

10장. 알림 시스템 설계

  • 알림은 속보, 제품 업데이트, 이벤트, 특가 정보 등 중요한 정보를 사용자에게 알려주는 역할을 함
  • 알림의 유형:
    • 모바일 푸시 알림
    • SMS 메시지
    • 이메일

 

 

1단계: 문제 이해 및 설계 범위 확장

면접관과 대화를 통해 도출한 요구사항:

  • 알림 유형: 푸시 알림, SMS 메시지, 이메일
  • 사용자는 가능한 한 빨리 알림을 받아야 하지만, 시스템이 과부하 상태일 경우 약간의 지연은 허용하는 연성 실시간 시스템
  • iOS 기기, 안드로이드 기기, 노트북/데스크탑 지원
  • 알림은 클라이언트 애플리케이션에서 보낼 수도 있고, 서버 측에서 스케줄링할 수도 있음
  • 사용자가 수신 거부(opt-out)할 수 있음
  • 하루에 모바일 푸시 알림 1천만 건, SMS 메시지 100만 건, 이메일 500만 건의 알림을 보낼 수 있어야 함

 

 

2단계: 개략적 설계안 제시 및 동의 구하기

알림 유형별 지원 방안

  • iOS 푸시 알림
    • 알림 제공자:
      • 알림 요청을 구성하고 Apple Push Notification Service(APNS)에 전송하는 역할
      • 다음과 같은 데이터를 포함하여 푸시 알림을 구성:
        • 단말 토큰: 푸시 알림 전송에 사용되는 고유 식별자
        • 페이로드: 알림 내용을 담은 JSON 딕셔너리
    • APNS:
      • Apple이 제공하는 원격 서비스로, iOS 기기로 푸시 알림을 전달함
    • iOS Device:
      • 알림을 실제로 수신하는 최종 사용자 단말기

  • 안드로이드 푸시 알림
    • APNS 대신 FCM 사용

  • SNS 메시지
    • SMS 메시지는 일반적으로 Twilio, Nexmo 등의 서드파티 SMS 서비스 공급자를 사용해 전송됨
    • 대부분은 유료 상용 서비스

  • 이메일
    • 기업들은 자체 이메일 서버를 구축할 수도 있지만, 대부분은 Sendgrid, Mailchimp와 같은 상용 이메일 서비스를 사용
    • 이들 서비스는 높은 전송 성공률과 데이터 분석 기능을 제공

  • 한 시스템으로 통합:

 

연락처 정보 수집 절차

  • 알림을 보내기 위해서는 모바일 디바이스 토큰, 전화번호, 또는 이메일 주소를 수집해야 함
  • 사용자가 앱을 설치하거나 회원가입을 할 때, API 서버가 사용자 연락처 정보를 수집하여 데이터베이스에 저장

  • 연락처 정보를 저장하기 위한 개략적인 데이터베이스 테이블 구조
    • 이메일 주소와 전화번호는 user 테이블에 저장
    • 디바이스 토큰은 device 테이블에 저장
    • 한 사용자는 여러 디바이스를 가질 수 있으므로, 푸시 알림은 해당 사용자의 모든 디바이스에 전송될 수 있음

 

알림 전송 및 수신 절차

  • 개략적 설계안 (초안)
    • 서비스 1~N
      • 알림 트리거 역할
      •  종류:
        • 마이크로서비스
        • 크론잡(Cron Job)
        • 분산 시스템
      • 예시:
        • 결제 서비스: 납부 기한을 이메일로 알림
        • 쇼핑 사이트: 배송 예정일을 SMS로 알림
    • 알림 시스템
      • 알림 전송의 중심 역할을 하는 시스템
      • 단일 알림 서버로 가정
      •  역할:
        • 서비스 1~N을 위한 API 제공
        • 써드파티 서비스용 알림 페이로드 생성
      • 제3자 서비스:
        • 실제 알림을 사용자에게 전달하는 역할
        • 주의사항:
          • 새로운 서비스를 통합하거나 기존 서비스를 제거하는 확장성을 고려해야 함 
          • 써드파티 서비스가 새로운 시장에서는 사용할 수 없을 수도 있음
            • 예: FCM은 중국에서 사용 불가
            • 대안: JPush, PushY 등

 

  •  
    • 이 설계의 문제점:
      • 단일 실패 지점(SPOF)
        • 하나의 알림 서버만 있을 경우, 해당 서버가 다운되면 전체 시스템이 마비됨
      • 규모 확장성 부족
        • 모든 기능(알림 처리, DB, 캐시 등)을 한 서버에서 처리하여 컴포넌트의 개별적 확장이 어려움
      • 성능 병목
        • 알림 생성, HTML 생성, 써드파티 응답 대기 등으로 인해 자원 사용량이 큼
        • 피크 시간대에는 시스템 과부하 발생 가능

 

  • 개략적 설계안 (개선된 버전)
    • 다음과 같이 개선:
      • 데이터베이스와 캐시를 알림 서버에서 분리
      • 알림 서버를 여러 개 배치하고, 자동 수평 확장 설정
      • 시스템 컴포넌트 간의 결합도를 낮추기 위해 메시지 큐 도입

 

  •  
    •  서비스 1~N:
      • 다양한 서비스들이 알림을 전송하기 위해 알림 서버의 API를 호출함
    • 알림 서버:
      • 알림 전송 API: 내부 서비스 또는 인증된 클라이언트만 접근 가능
      • 알림 검증: 이메일, 전화번호 등의 기본 유효성 검사 수행
      • DB 또는 캐시 질의: 알림 생성에 필요한 데이터 조회
      • 생성된 알림 데이터를 메시지 큐에 넣어 병렬 처리 준비
    • 이메일 형태의 알림을 보내는 데 사용되는 API 예시:

  •  
    • 캐시:
      • 사용자 정보, 디바이스 정보, 알림 템플릿 등이 캐싱됨
      • 빠른 조회를 통해 성능 향상
    • DB:
      • 사용자, 알림, 설정 관련 정보 저장
    • 메시지 큐:
      • 시스템 컴포넌트 간 비동기 처리 및 버퍼링 역할
      • 알림 유형별로 개별 큐를 사용하여 장애 격리:
        • iOS 푸시 큐, Android 푸시 큐, SMS 큐, 이메일 큐 등
      • 특정 써드파티 서비스가 중단되어도 다른 큐에 영향 없음
    • 작업 서버(workers):
      • 메시지 큐에서 알림 이벤트를 가져와 해당 알림 유형에 맞는 써드파티 서비스에 전송
    • 써드파티 서비스:
      • 앞서 설명한 FCM, APNS, Twilio, SendGrid 등
    • 사용자 단말:
      • iOS, Android, 이메일 앱, SMS 앱을 통해 실제 알림 수신
    • 전체 흐름:
      1. 서비스가 알림 서버의 API를 호출하여 알림 전송 요청
      2. 알림 서버가 DB 또는 캐시에서 사용자 정보, 디바이스 토큰 등을 조회
      3. 알림 이벤트를 적절한 메시지 큐에 전송 (예: iOS 큐)
      4. 작업 서버가 메시지 큐에서 알림 이벤트를 가져옴
      5. 작업 서버가 써드파티 서비스에 알림 전송
      6. 써드파티 서비스가 사용자에게 알림 전달

 

 

3단계: 상세 설계

안정성

분산 환경에서 알림 시스템을 설계할 때 다음의 사항을 고려하여 안정성을 확보해야 함

  • 데이터 손실 방지
    • 알림 시스템의 가장 중요한 요구사항 중 하나는 데이터 손실이 없어야 한다는 것
    • 알림은 지연되거나 순서가 바뀔 수는 있어도 절대 유실되어서는 안 됨
    • 이를 위해:
      • 알림 데이터를 데이터베이스에 영구 저장
      • 재시도 메커니즘(Retry mechanism)을 도입

  • 알림 중복 전송 방지
    • 알림은 대부분 한 번만 전송되지만, 분산 시스템의 특성상 중복이 발생할 수 있음
    • 중복 전송을 줄이기 위한 메커니즘 도입
      • 보내야 할 알림이 도착하면 이벤트 ID 검사하여 이전에 본 적이 있는 이벤트인지 확인
      • 중복된 이벤트는 버리고, 그렇지 않으면 알림 발송

 

추가로 필요한 컴포넌트 및 고려사항

  • 알림 템플릿
    • 대규모 알림 시스템은 매일 수백만 개의 알림을 보냄
    • 대부분의 알림은 유사한 형식을 따름
    • 모든 알림을 매번 새로 만들기보다 알림 템플릿을 도입해 효율적으로 관리하는 것이 좋음
    • 장점:
      • 일관된 형식 유지
      • 오류율 감소
      • 개발 시간 단축
  •  알림 설정
    • 사용자들은 너무 많은 알림을 받으면 피로감을 느끼므로, 세부적인 설정 권한을 부여해야 함
    • 알림 설정 테이블에 설정 정보를 보관하여, 알림을 보내기 전에 해당 사용자가 수신 동의를 했는지 먼저 확인해야 함
  • 전송률 제한
    • 사용자가 너무 많은 알림을 받지 않도록 제한
    • 너무 자주 전송하면 수신 거부로 이어질 수 있음
  • 재시도 방법
    • 써드파티 서비스가 실패하면 메시지를 다시 큐에 넣고 재시도
    • 문제가 지속될 경우, 개발자에게 통지
  • 푸시 알림과 보안
    • iOS/Android 앱에서는 appKey와 appSecret을 사용해 인증
    • 인증된 클라이언트만 API 호출 가능
  • 큐 모니터링
    • 큐에 쌓인 알림 개수가 중요한 메트릭
    • 큐가 너무 크면 작업 서버가 부족하다는 의미
    • 워커 수를 늘려 알림 지연 최소화
  • 이벤트 추적
    • 알림 확인율, 클릭율, 실제 앱 사용으로 이어지는 비율 같은 메트릭을 분석

 

수정된 설계안

 

  • 알림 서버에 인증 및 전송률 제한 추가:
    • 인증: 인증된 클라이언트만 알림 API 사용 가능
    • 전송률 제한: 과도한 알림 전송 방지
  • 재시도 기능 추가:
    • 알림 전송 실패 시 메시지를 다시 큐에 넣고 사전 정의된 횟수만큼 재시도
  • 알림 템플릿 추가:
    • 일관된 포맷으로 효율적으로 알림 생성 가능
  • 모니터링 및 추적 시스템 추가:
    • 시스템 상태를 점검하고, 향후 개선을 위한 데이터 수집

 

 

4단계: 마무리

이 장에서 설계한 시스템:

  • 확장 가능
  • 푸시, SMS, 이메일 등 다양한 채널을 지원
  • 시스템 구성 요소 간 결합도 낮추기 위해 메시지 큐를 사용

설계 고려사항:

  • 안정성: 실패율을 최소화하기 위해 재시도 메커니즘 도입
  • 보안: appKey/appSecret을 활용한 API 인증
  • 이벤트 추적 및 모니터링: 알림 수명주기 전 단계에 분석 기능 포함
  • 사용자 설정: 수신 거부 설정 시 전송 차단
  • 전송률 제한: 사용자에게 너무 많은 알림을 보내지 않도록 제한 설정