알림 시스템 설계 개요

알림 시스템은 이벤트, 선물 중요할 만한 정보를 비동기적으로 제공한다.  알림 시스템은 단순히 모바일 푸시 알림에 한정되지 않는다. 

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

대상은 푸시 알림, SMS 메시지, 그리고 이메일이 될 수 있다.  실시간 시스템임을 감안한다. 지원하는 단말은 iOS 단말, 안드로이드 단말, 그리고 랩톱/데스크톱이다.

  • 지원 알림 유형: 푸시, SMS, 이메일
  • 성능 특성: 연성 실시간(soft real-time) 시스템, 높은 부하 시 약간의 지연 허용
  • 사용자 설정: opt-out 기능(사용자가 알림을 받지 않도록하는 기능) 지원

중요한건 확장성을 고려해 천만 건의 모바일 푸시 일림, 백만 건의 SMS 메시지, 5백만 건의 이메일 보낼 수 있어야 한다. 

  • 단말 토큰
    • 페이로드
    • 알림 내용을 담은 JSON 딕셔너리이다. 
{
    "aps" : {
                "alert" : {
                     "title": "Game Reqeust",
                     "body" : "body",
                     "action-loc-key":"PLAY"
                },
                "badge": 5
            }
}

 

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

알림 유형별 지원 

iOS 푸시 알림

알림 제공자 -> APNS -> iOS 단말

  • APNS : 애플이 제공하는 원격 서비스. 푸시 알림을 IOS 장치로 보내는 역할을 담당
  • iOS 단말 : 푸시 알림을 수신하는 사용자 단말

안드로이드 푸시 알림

APNS 대신 FCM 을 사용한다. 

연락처 정보 수집 절차

알림을 보내려면 모바일 단말 토큰, 전화번호, 이메일 주소 등의 정보가 필요하다. 

API 서버는 해당 사용자의 정보를 수집하여 데이터베이스에 저장한다. 

 

알림 전송 및 수신 절차

1부터 N까지 서비스 마이크로 서비스, 크론잡 등 시스템 컴포넌트라고 하면 실제로 구현되는 서비스를 고려해봤을때 과금 서비스, 배송 알림을 보내는 쇼핑몰 등이 그 예다. 

알림 시스템 : 서비스 1-N 에 알림 전송을 위한 API 제공해야되고 제 3자 서비스에 전달할 알림 페이로드를 만들어야 한다. 

제 3자 서비스 : 국가, 지역에 맞춰 서비스 가능한 지역인지 확인해보고 서비스를 사용해야 한다.

각 서비스에서 알림 서버로 알림 생성 요청을 보내게 된다. 알림 서버는 DB에 저장되어 있는 사용자의 메타 데이터를 조합해 알림 데이터를 생성하게 된다. 그리고 이 알람은 알림에 맞는 이벤트(안드로이드 푸시 알림, iOS 푸시 알림 등)를 생성해 해당 이벤트를 위한 목적으로 큐에 넣게 된다. 디바이스 푸시 큐(메시지 큐)에 쌓여있는 알림은 작업 서버가 꺼내서 알림 서비스로 전달한다. 

메시지 큐를 도입하게 됨으로써 알림 데이터 유실을 막을 수 있고 컴포넌트간 의존성을 최소화할 수 있다. 만약, 메시지 큐가 존재하지 않았다면 알림 시스템의 작업이 끝날때까지 기다려야 다음 작업을 실행할 수 있을 것이다. 아래 아키텍처에서 메시지 큐를 추가해 줬기에 알림 서버와 써드파티 서비스는 의존성을 최소화하여 할 수 있게 되었다. 또, 메시지 큐를 도입하면서 이메일, SMS, APN, FCM 등 어느 하나의 서비스가 장애가 발생한다 하더라도 나머지 유형의 알림은 정상적으로 보낼 수 있다.

process

1. api 호출해서 알림 서버로 알림을 보냄 

2. 알림 서버는 사용자 정보, 단말  토큰 메타데이터를 캐시나 데이터베이스에서 가져온다. 

3. 알림서버는 알림에 맞는 이벤트를 만들어서 해당 이벤트를 위해 큐에 넣는다. 

4. 작업 서버는 메시지 큐에서 알림 이벤트를 꺼낸다. 

5. 작업 서버는 알림을 제 3자 서비스로 보낸다. 

6. 제3자 서비스는  사용자 단말로 알림을 전송한다. 

 

상세설계

안정성

데이터 손실 방지

  • 알림은 지연되거나 순서가 틀려도 되지만 사라지면 문제가 된다. 알림 시스템은 알림 데이터를 데이터베이스에 보관한다. 재시도 메커니즘을 구현해야 한다. 
  • 알림 로그 데이터베이스를 유지하는것도 하나의 방법이 될 수 있다. 
  • 알림이 도착하면 이벤트 ID 를 검사해서 이전에 본 적이 있는 이벤트인지 검사한다. 중복되는 이벤트이면 버리고 그렇지 않으면 알림을 발송한다. 

위 아키텍처를 수정하면 아래와 같다. 

알림 서버에 인증, 전송률 제한을 추가한다. 또, 모니터링과 추적 시스템을 추가하여 시스템 상태를 확인하고 시스템을 개선하기 쉽도록 한다. 

추가로 고려해야할 사항

  • 템플릿 이용, 일관성 유지 및 오류 가능성을 줄일 수 있다. 

알림 설정 

  • 사용자가 알림 설정을 상세히 조정할 수 있도록 한다. 
user_id bigint 비고
channel varchar  알림이 전솔될 채널, 푸시 알림, 이메일, SMS 등
opt_in  boolean 해당 채널로 알림을 받을 것인지 여부

전송률 제한 

  • 사용자에게 너무 많은 알림을 보내지 않도록 한다. 

재시도 방법

  • 제 3자 서비스가 알림 전송에 실패하면, 해당 알림을 재시동 전용 큐에 넣는다. 

모니터링

  • 큐에 쌓인 알림의 개수가 크면 이벤트를 빠르게 처리하지 못하고 있다는 지표가 된다. 

ref

https://dewble.tistory.com/entry/system-design-notification