들어가기 앞서

여러분들의 휴대폰에도 여러 알람들이 울리시나요? 이번장에서 알아볼 내용은 알림 시스템 설계입니다. 최근 온라인 서비스에서 알람의 역할은 매우 중요하다고 생각합니다. 이벤트 정보, 할인 쿠폰 제공, 주식 가격 변동 알림 까지 다양한 정보를 푸시 알림을 통해 서비스 이용자에게 발송하고 있습니다. 푸시 알람 뿐만 아니라 카카오톡, 문자, 메일까지 다양한 매체가 활용되고 있습니다.
알림 시스템 설계
알림 시스템은 최신 뉴스, 제품 업데이트, 이벤트, 선물 등 고객에게 중요한 정보를 비동기적으로 제공합니다. 알림은 모바일 푸시 알림에 한정되지 않고 SMS메시지, 메일등 다양한 채널로 활용되고 있습니다.
1단계 : 문제 이해 및 설계 범위 확장
하루에 백만 건 이상의 알림을 처리하는 확장성 높은 시스템을 구축하는게 쉬운 과제는 아니다. 요구사항은 다음과 같다.
- 푸실 알림, SMS메시지, 이메일을 사용할 수 있어야 한다.
- 연성 실시간 시스템이라 가정한다. 가능한 빨리 전달되어야 하지만 시스템에 높은 부하가 걸렸을 때 약간의 지연은 무방하다.
- iOS, 안드로이드, 데스크톱 모두 지원해야 한다.
- 사용자가 알림을 받지 않도록 설정 할 수 있어야 한다.
- 천만건의 푸시 알림을 보낼 수 있어야 한다.
2단계 : 개략적 설계안 제시 및 동의 구하기
1. 알림 유형별 지원 방안

iOS 푸시 알림
- 알림 제공자 : 알림 요청을 만들어 애플 푸시 알림 서비스(APNS)로 보내주는 주체다. 알림 요청을 만들려면 다음과 같은 데이터가 필요하다.
- 단말 토큰 : 알림 요청을 보내는데 필요한 고유 식별자다.
- 페이로드 : 알림 내용을 담은 JSON 딕셔너리다.
- APNS : 애플이 제공하는 원격 서비스다. 푸시 알림을 iOS장치로 보내는역할을 담당한다.
- iOS 단말 : 푸시 알림을 수신하는 사용자 단말이다.
안드로이드 푸시 알림
안드로이드 푸시 알림도 비슷한 절차로 전송된다. APNS대신 FCM을 사용한다.
SMS
SMS메시지를 보낼 때는 보통 트윌리오, 넥스모 같은 제 3자 사업자의 서비스를 많이 이용하며 이런 서비스는 대부분 사용 서비스라서 이용 요금을 내야 한다.
이메일
이메일 역시 비슷하다. 많은 회사들이 이메일 서버를 구축할 역량을 갖추었지만 사용 서비스를 많이 사용한다.
2. 연락처 정보 수집 절차
알림을 보내기 위해서는 모바일 단말 토큰, 전화번호, 이메일 정보가 필요하다. 당연하지만 회원 가입을 하거나 처음 앱을 설칠할 때 해당 사용자 정보를 수집하여 데이터베이스에 저장해야 한다. 테이블을 구성 할 때 한 사용자는 여러 단말을 가질 수 있기 때문에 1:N 구조가 되어야 하며 모든 단말에 알림이 전송되어야 한다.
3. 알림 전송 및 수신 절차
- 1~N 서비스 : 이들은 각각 마이크로서비스, 크론잡, 분산 시스템 컴포넌트 이다. 주문, 결제, 상품과 같은 도메인이며 사용자에게 알림을 보내려고 하는 서비스다.
- 알림 시스템 : 아림 전송/수신을 처리하는 핵심 시스템이다.
- 제3자 서비스 : 실제로 알림을 전달한는 역할을 한다. 제3자 서비스와 연동을 진행할 때는 확장성을 유의해야 한다. 쉽게 새로운 서비스를 통합하거나 기존 서비스를 제거 할 수 있어야 한다. 예를들어 FCM은 중국에서 사용할 수 없다. 중국에서는 제이푸시 라는 것을 사용해야 하는데, 이처럼 외부 서비스에 대해서는 쉽게 변경할 수 있도록 느슨한 결합을 유지하는 것이 좋다.

다음 설계에는 몇가지 문제가 있다.
- SPOF : 알림 서비스에 서버가 하나 밖에 없기에, 알림 서비스가 장애가 발생하면 전체 서비스의 장애로 이어진다.
- 규모 확장성 : 한 개의 서비스로 푸시 알림에 관계된 모든 것을 처리하므로, 데이터베이스나 캐시 등 주요 컴포넌트의 규모를 개별적으로 늘릴 방법이 없다.
- 성능 병목 : 제3자 서비스를 신뢰하면은 안된다. 제3자 서비스의 응답이 오래 걸릴수도 있으며, 제3자 서비스에 장애가 발생했을 수도 있다. 따라서 제3자 서비스의 응답을 기다리는 일은 사용자 트래픽이 많이 몰리는 시간에 과부하 상태에 빠질 수 있다.
개선된 설계안
- 위에서 언급한 문제점을 개선해 보도록 하자.
- 데이터베이스와 캐시를 알림 시스템의 주 서버에서 분리한다.
- 알림 서버를 증설하고 자동으로 수평적 규모 확장이 이루어질 수 있도록 한다.
- 메시지 큐를 이용해 시스템 컴포넌트 사이의 강한 결합을 끊는다.

다음과 같이 기능을 구현해야 한다.
- 알림 서버 :
- 알림 전송 API: 스팸 방지를 위해 인증된 클라이언트만 이용 가능하도록 해야 한다.
- 알림 검증 : 이메일 주소, 전화번호 등 기본적인 검증을 수행해야 한다.
- 데이터베이스, 캐시 : 알림에 포함시킬 데이터를 가져오도록 기능을 구현해야 한다.
- 알림 전송 : 알림 데이터를 메시지 큐에 넣는다.
- 캐시 : 사용자 정보, 단말 정보, 알림 템플릿 등을 캐시한다.
- 메세지 큐 :
- 시스템 간 의존성을 제거하기 위해 사용한다.
- 다량의 알림이 전송되어야 하는 경우를 대비한 버퍼 역할도 한다.
- 따라서 제3자 서비스 가운데 하나에 장애가 발생해도 다른 종류의 알림은 정상 동작하게 된다.
3. 상세 설계
조금 더 시스템을 고도화 하기 위해 안정성과 알림 템플릿, 알림 설정, 전송률 제한, 재시도 메커니즘, 보안, 모니터링등 추가적인 작업이 더 필요하다.
안정성
분산 환경에서 운영될 알림 시스템을 설계할 때는 안정성을 확보하기 위한 사항 몇 가지를 반드시 고려해야 한다.
1. 데이터 손실 방지
알림 전송 시스템의 가장 중요한 요구사항 가운데 하나는 어떤 상황에서도 알림이 손실되면 안 된다는 것이다. 알림이 지연되거나 순서가 틀려도 괜찮지만 사라지면 곤란하다. 손실을 방지하기 위해서는 알림 데이터를 데이터베이스에 보관하고 재시도 메커니즘을 구현해야 한다. 그림 처럼 알림 로그 데이터베이스를 유지하는 것도 한가지 방법이다.

2. 알림 중복 전송 방지
같은 알림이 여러 번 반복되는 것을 완전히 막는 것은 가능하지 않다. 대부분의 경우 알림은 딱 한 번만 전송되겠지만, 분산 시스템 특성상 각끔은 같은 알림이 중복되어 전송될 수 도 있다. 따라서 중복을 탐지하는 메커니즘을 도입하고 오류를 신중하게 처리해야 한다.
보내야 할 알림이 도착하면 그 이벤트 ID를 검사하여 이전에 본 적이 있는 이벤트인지 살핀다. 중보고딘 이벤트라면 버리고, 그렇지 않으면 알림을 발송한다. 중복 전송을 100% 방지하는 것이 불가능한 이유에 대해서는 아래 링크를 참고해 주시면 감사하겠습니다.
가상 사례로 배우는 대규모 시스템 설계 기초 (feat. 5장)
추가로 필요한 컴포넌트 및 고려사항
알림 템플릿, 알림 설정, 이벤트 추적, 시스템 모니터링, 처리율 제한 등 알림 시스템 구현을 위해 필요한 컴포넌트에 대해 알아보자
1. 알림 템플릿
대부분의 알림 메시지는 비슷한 형식이다. 알림 메시지를 다시 만들 필요 없도록 템플릿을 작성해 두면 좋다.
2. 알림 설정
사용자가 알림 설정을 상세히 조정할 수 있도록 하는 것이 좋닫.
3. 전송률 제한
사용자에게 너무 낳은 알림을 보내지 않도록 알림의 빈도를 제한하면 좋다. 알림을 너무 많이 보내면 사용자가 알림 기능을 사용하지 않을 가능성이 크다.
4. 재시도 방법
제3자 서비스가 알림 전송에 실패하면, 해당 알림을 재시도 전용 큐에 넣는다. 같은 문제가 계속해서 발생하면 개발자에게 통지한다.
5. 푸시 알림과 보안
appKey와 appSecret을 사용하여 보안을 유지한다. 인증된 혹은 승인된 클라이언트만 api를 통해 알림을 보낼 수 있다.
가상 사례로 배우는 대규모 시스템 설계 기초 (feat. 6장)
6. 큐 모니터링
알림 시스템을 모니터링 할 때 메트릭 하나는 큐에 쌓인 알림의 개수이다. 이 수가 너무 크면 작업 서버들이 이벤트를 빠르게 처리하고 있지 못하는 뜻이다. 그런 경우 작업 서버를 증설하는게 바람직 하다.
7. 이벤트 추적
알림 확인율, 클릭율, 실제 앱 사용으로 이어지는 비율 같은 메트릭은 사용자를 이해하는데 중요하다. 데이터 분석 서비스는 보통 이벤트 추적 기능도 제공한다.
수정된 설계안

- 알림 서버에 인증과 전송률 제한 기능이 추가 되었다.
- 전송 실패에 대응하기 위한 재시도 기능이 추가 되었다.
- 전송 템플릿을 사용하여 알림 생성 과정을 단순화하곡 알림 내용의 일관성을 유지한다.
- 모니터링과 추적 시스템을 추가하여 시스템 상태를 확인하고 추후 시스템을 개선하기 쉽도록 하였다.
'기술서적으로 배우는 기술' 카테고리의 다른 글
| 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (feat. 12장 채팅 시스템 설계) (3) | 2025.01.19 |
|---|---|
| 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (feat. 11장 뉴스 피드 시스템 설계) (3) | 2025.01.16 |
| 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (feat. 8장 URL 단축기 설계) (1) | 2025.01.15 |
| 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (feat. 7장 분산 시스템을 위한 유일 ID 생성기 설계) (4) | 2025.01.11 |
| 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (feat. 4장 처리율 제한 장치의 설계) (3) | 2025.01.10 |