Design Notification System
알림 시스템은 클라이언트에게 정보를 전달하는 시스템으로, 현대 서비스에서는 중요한 부분으로 자리 잡았다.
알림 시스템은 모바일 푸시 알림 / SMS 메시지 / 이메일 세 가지로 분류해볼 수 있다.
- 푸시 알림 / SMS 메시지 / 이메일 알림 지원
- 가능한 빨리 전달되어야 하지만 높은 부하 시 약간의 지연은 무방한 연성 실시간(soft realtime) 시스템
- iOS / android / 웹 등 다양한 플랫폼 지원
- 서버 측 스케줄링과 클라이언트 애플리케이션에서 알림 생성
- 알림 수신 거부 기능
- 하루 1,000만 건의 푸시 알림 / 100만 건의 SMS 메시지 / 500만 건의 이메일 알림 전송
알림 유형별 지원 방안
Section titled “알림 유형별 지원 방안”- iOS 푸시 알림 / Android 푸시 알림: iOS와 Android 푸시 알림은 각각 APNS와 FCM을 사용한다.
알림 제공자 -> APNS / FCM -> 디바이스순으로 전달하게 된다.
- SMS 메시지: 트윌리오 / 넥스모 같은 제 3사업자의 서비스를 많이 이용
- 이메일: 고유 이메일 서버를 구축할 수도 있지만, 안정성과 데이터분석 서비스를 위해 Sendgrid / Mailchimp 같은 서비스도 많이 이용
연락처 정보 수집 절차
Section titled “연락처 정보 수집 절차”알림을 전송하기 위해선 모바일 단말 토큰 / 전화번호 / 이메일 등의 정보가 필요하다.
해당 정보를 수집하기 위해서 사용자가 앱을 설치하거나 계정을 등록하면 API 서버에서 해당 정보를 데이터베이스에 저장한다.
알림 전송 및 수신 절차
Section titled “알림 전송 및 수신 절차”개략적인 플로우는 알림 생성 서비스 -> 알림 시스템 -> 서드파티 서비스 -> 디바이스 순으로 전달될 수 있다.
- 알림 생성 서비스(여러 개일 수 있음): 마이크로서비스 형태거나, 크론잡 등등 알림을 생성하는 서비스
- 알림 시스템: 알림 생성 서비스에서 생성된 알림을 받아서 전송하는 서비스
- 서드파티 서비스: 알림을 실제로 전달하는 역할을 하는 서비스(APNS / FCM / 트윌리오 / 넥스모 / Sendgrid / Mailchimp 등)
- 디바이스: 알림을 받는 디바이스
여기서 알림 시스템을 하나의 서비스로 구현할 수도 있지만, 아래의 이유로 분리하는 것이 좋다.
- SPOF(Single Point of Failure): 알림 시스템이 다운되면 알림 전송 중단 가능성 존재
- 성능 병목: 알림 처리 시 리소스가 많이 필요한 경우, 시스템 과부하 가능성 존재
- 규모 확장성: 한 대의 서비스로 모든 트래픽을 처리하기 힘들어 지는 것을 대비하여, 데이터베이스나 캐시 등 중요 컴포넌트 규모 확장 방법 고려
알림 시스템 설계
Section titled “알림 시스템 설계”위의 문제점을 해결하기 위해 다음과 같은 방향으로 개선해 볼 수 있다.
- 데이터베이스와 캐시를 알림 시스템의 주 서버에서 분리
- 알림 서버를 증설하고 자동으로 수평적 규모 확장이 가능하도록 설계
- 메시지 큐를 이용해 시스템 컴포넌트 사이 강한 결함을 줄임(de-coupling)

각 컴포넌트는 다음과 같은 역할을 수행한다.
- 알림 서버
- 알림 전송 API 제공: 서비스에서 알림을 생성하고 전송할 수 있도록 API 제공
- 알림 검증: 이메일 / 전화번호 등 기본적인 검증 수행
- 데이터베이스 or 캐시 질의: 알림에 포함시킬 데이터 조회
- 알림 전송: 알림 데이터를 메시지 큐에 전달
- 캐시: 사용자 정보 / 단말 정보 / 알림 템플릿 등 캐싱
- 데이터베이스: 사용자 정보 / 알림 / 설정 등 다양한 정보 저장
- 메시지 큐: 시스템 컴포넌트 간 의존성 제거를 위해 사용, 대량 알림이 전송되어야 하는 경우 대비한 버퍼 역할도 수행
- 작업 서버: 메시지 큐에서 전송할 알림을 꺼내 서드파티 서비스로 전달하는 역할 수행
결과적으로 알림 시스템은 다음과 같이 동작하게 된다.
- API를 호출하여 알림 서버로 알림 전송
- 알림 서버는 사용자 정보 / 단말 토큰 / 알림 설정 같은 메타데이터를 캐시나 데이터베이스에서 조회
- 알림 서버는 전송할 알림에 맞는 이벤트를 생성해 해당 이벤트를 위한 큐에 전달
- 작업 서버는 메시지 큐에서 알림 이벤트를 꺼내 서드파티 서비스로 전달
- 서드파티 서비스에서 디바이스로 실제 알림 전송
- 데이터 손실 방지
- 알림이 지연되거나 순서가 뒤바뀌는 것은 큰 문제가 되지 않을 수 있지만, 알림이 전송되지 않는 것은 큰 문제가 될 수 있음
- 이를 위해 알림 데이터를 데이터베이스에 보관하고 재시도 메커니즘 필요
- 알림 중복 전송 방지
- 완벽하게 중복을 방지하는 것은 불가능하는 것에 가깝지만, 중복 전송을 최소화 해야 함
- 이벤트 ID 검사하는 방식 등 중복 방지 로직 추가 필요
추가 고려 사항
Section titled “추가 고려 사항”- 알림 템플릿: 대부분 형식이 비슷하기 때문에 템플릿을 사용해 알림을 생성하는 것이 효율적일 수 있음
- 알림 설정: 사용자의 알림 설정을 보관하기 위해 알림 설정 테이블을 두어 사용자가 알림을 받을지 여부를 설정할 수 있도록 함
- 재시도 방법: 서드파티 서비스에서 알림 전송 실패 시 해당 알림을 재시도 전용 큐에 넣어 재시도하는 방법을 사용
- 보안: iOS / Android 경우 특정 키를 사용해 승인된 클라이언트만 알림을 보낼 수 있는데, 다른 클라이언트(SMS / 이메일)도 같은 방법으로 보안을 강화할 수 있음
- 큐 모니터링: 특정 큐에 쌓인 이벤트가 너무 많아지면(빠르게 처리 못하고 있음) 시스템에 영향을 줄 수 있으므로 큐 모니터링이 필요