본문 바로가기
🏛️ Architecture

[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 10장 알림 시스템 설계

by GroovyArea 2023. 3. 18.

알림 시스템은 어느 서비스나 항상 고민하게 되는 부분이라 생각한다.
실제로 서비스를 구현할 때, 다양한 고민들을 하게 되는데, 설계에 대한 초점에서 바라본 건 새로웠다.

알림 시스템

  • 고객에게 중요할 만한 정보를 비동기적으로 전송
  • 모바일 푸시 알림, SMS 메시지, 이메일 세 가지로 분류

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

  • 시스템이 지원하는 알림 종류
    • 푸시 알림, SMS 메시지, 이메일
  • 실시간 시스템 여부
    • 연성 실시간 시스템이라고 가정 (시스템 부하 시 약간의 지연 무방)
  • 지원해야 하는 종류의 단말
    • iOS, 안드로이드, 랩톱/데스크톱
  • 알림을 만들 수 있는 주체
    • 클라이언트 애플리케이션 or 서버 측의 스케줄링
  • 알림을 받지 않도록 설정도 가능해야 함
  • 하루에 보낼 수 있어야 하는 양
    • 천만 건의 모바일 푸시 알림, 백만 건의 SMS 메시지, 5백만 건의 이메일

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

알림 유형별 지원 방안

iOS 푸시 알림

  • 알림 제공자
    • 알림 요청을 만들어 애플 푸시 알림 서비스(APNS)로 보내는 주체
    • 단말 토큰(고유 식별자), 페이로드(알림 내용을 담은 JSON 딕셔너리) 데이터가 필요
  • APNS
    • 애플이 제공하는 원격 서비스
    • 푸시 알림을 iOS 장치로 보내는 역할을 담당
  • iOS 단말
    • 푸시 알림을 수신하는 사용자 단말

안드로이드 푸시 알림

  • iOS 와 비슷한 절차이며 APNS 대신 FCM(Firebase Cloud Messaging)을 사용하는 점이 다름

SMS 메시지

  • 보통 트윌리오, 넥스모 같은 제3 사업자의 서비스를 많이 이용
    • 사용 서비스라 이용요금 필요

이메일

  • 대부분의 회사가 고유 이메일 서버를 구축할 수 있지만 사용 이메일 서비스 많이 이용
    • 센드그리드, 메일침프 등 (높은 전송 성공률, 데이터 분석 서비스)

연락처 정보 수집 절차

  • 사용자가 앱 설치, 계정 등록 등을 하면 API 서버는 해당 사용자의 정보를 수집하여 데이터 베이스에 저장
    • 이메일 주소와 전화번호는 user 테이블에 저장
    • 단말 토큰은 device 테이블에 저장 (한 사용자가 여러 단말을 가질 수 있으므로)

알림 전송 및 수신 절차

개략적 설계안 (초안)

  • 1부터 N까지의 서비스
    • 서비스 각각은 마이크로서비스, 크론잡, 분산 시스템 컴포넌트 등 일 수 있음
  • 알림 시스템
    • 알림 전송/수신 처리의 핵심
    • 초안 설계안에선 1개 서버만 사용하는 시스템으로 가정
  • 제3자 서비스
    • 사용자에게 알림을 실제로 전달하는 역할
    • 통합 진행 시 확장성을 유의해야 함 (새로운 서비스 통합 or 기존 서비스 제거 등등 ...)
  • 사용자는 자기 단말에서 알림을 수신
  • 초안 설계안의 몇 가지 문제
    • SPOF (알림 서비스에 서버가 하나밖에 없으므로)
    • 규모 확장성 (한 대 서버이므로)
    • 성능 병목 (알림을 처리하고 보내는 것은 자원을 많이 필요로 함, 시스템 과부하 상태에 빠질 수도 있음)

개략적 설계안 (개선된 버전)

  • 개선 방향
    • 데이터베이스와 캐시를 알림 시스템의 주 서버에서 분리
    • 알림 서버를 증설하고 자동으로 수평적 규모 확장이 이루어질 수 있도록 함
    • 메시지 큐를 이용해 시스템 컴포넌트 사이의 강한 결합을 끊음
  • 알림 서버가 제공하는 기능
    • 알림 전송 API (사내 서비스, 인증된 클라이언트)
    • 알림 검증
    • 데이터베이스 또는 캐시 질의
    • 알림 전송 (메시지 큐에 알림 데이터를 넣음)
  • 캐시
    • 사용자 정보, 단말 정보, 알림 템플릿 등을 캐시 함
  • 데이터베이스 (DB)
    • 사용자, 알림, 설정 등 다양한 정보를 저장
  • 메시지 큐
    • 시스템 컴포넌트 간 의존성을 제거하기 위해 사용
    • 다량의 알림이 전송되어야 할 경우를 대비해 버퍼 역할도 수행
    • 알림의 종류별로 별도 메시지 큐를 사용
  • 작업 서버
    • 메시지 큐에서 전송할 알림을 꺼내서 제3자 서비스로 전달하는 역할을 담당하는 서버
  • 알림 전송 과정
    • API를 호출하여 알림 서버로 알림을 보냄
    • 알림 서버는 메타데이터를 캐시나 DB에서 가져옴
    • 알림 서버는 전송할 알림에 맞는 이벤트를 만들어서 해당 이벤트를 위한 큐에 넣음
    • 작업 서버는 메시지 큐에서 알림 이벤트를 꺼냄
    • 작업 서버는 알림을 제3자 서비스로 보냄
    • 제3자 서비스는 사용자 단말로 알림을 전송

3단계 : 상세 설계

안정성

데이터 손실 방지

  • 어떤 상황에서도 알림이 소실되면 안 됨
    • 지연이나 순서가 틀리는 것보다 심각함
  • 알림 데이터를 DB에 보고하고 재시도 메커니즘 구현 필요

알림 중복 전송 방지

  • 완전히 막는 것은 불가능
  • 중복을 탐지하는 메커니즘 도입
  • 오류를 신중히 처리
  • 보내야 할 알림의 이벤트 ID를 검사하여 본 적이 있는 이벤트인지 살펴봄

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

알림 템플릿

  • 알림의 유사성을 고려하여 알림 메시지의 모든 부분을 다시 만들 필요를 덜어줌
  • 인자, 스타일, 추적 링크를 조정하여 알림을 만들어 내는 틀
  • 일관성 유지 및 오류를 줄이고 알림 작성 시간 감소

알림 설정

  • 알림 설정 테이블에 보관
  • user id, channel, 해당 채널로 알림을 받을 것인지 등의 정보 저장
  • 특정 종류의 알림을 보내기 전에 해당 정보를 조회

전송률 제한

  • 한 사용자가 받을 수 있는 알림의 빈도 제한
  • 알림을 너무 많이 보내면 클라이언트가 알림을 끌 수 있으므로 제한

재시도 방법

  • 알림 전송에 실패 시 해당 알림을 재시도 전용 큐에 넣음
  • 같은 문제가 계속해서 발생하면 개발자에게 통지

푸시 알림과 보안

  • iOS와 안드로이드 앱의 경우 알림 전송 API는 appKey와 appSecret을 사용하여 보안 유지
  • 인증되거나 승인된 클라이언트만 알림을 보낼 수 있음

큐 모니터링

  • 큐에 쌓인 알림의 개수는 알림 시스템 모니터링의 중요한 메트릭
  • 이 수가 너무 크면 작업 서버들이 이벤트를 빠르게 처리하지 못한 것 -> 서버 증설 필요

이벤트 추적

  • 알림 확인율, 클릭률, 실제 앱 사용 등의 비율 같은 메트릭은 사용자를 이해하는데 중요
  • 보통은 알림 시스템은 데이터 분석 서비스와도 통합해야만 함

수정된 설계안

  • 알림 서버에 인증과 전송률 제한 기능 추가
  • 전송 실패에 대응하기 위한 재시도 기능도 추가 (다시 큐에 넣고 지정된 횟수만큼 재시도)
  • 전송 템플릿을 사용하여 알림 생성 과정을 단순화하고 알림 내용의 일관성을 유지
  • 모니터링과 추적 시스템을 추가

4단계 : 마무리

  • 알림 필수불가결한 기능
  • 메시지 큐를 적극적으로 사용하여 시스템 컴포넌트 사이의 결합도를 낮출 것
  • 최적화 기법
    • 안정성
    • 보안
    • 이벤트 추적 및 모니터링
    • 사용자 설정
    • 전송률 제한
반응형