알렉스 쉬 님의 "가상 면접 사례로 배우는 대규모 시스템 설계 기초" 책을 정리한 포스팅 입니다.
1. 요구 사항
항목 | 내용 |
알림 종류 | 모바일 푸시, SMS, 이메일 |
전송 대상 기기 | iOS, Android, PC/Laptop |
전송 타이밍 |
- 실시간 (Soft real-time)
- 지연 허용: 수 초~수십 초 |
알림 생성 주체 | 클라이언트 앱 or 서버 스케줄러 |
Opt-out 지원 | 개별 사용자 알림 수신 설정 가능 |
일일 전송량 규모 |
- Push: 1천만
- SMS: 100만 - Email: 500만 |
확장성 수준 |
고부하 지원 필요 (스케일 아웃 가능 구조 요구됨)
|
2. 개략적 설계안
알림 유형별 지원 방안
알림 유형 | 주요 구성 요소 | 동작 과정 / 설명 |
iOS 푸시 알림 | - 알림 제공자 - APNS (Apple Push Notification Service) - iOS 단말 |
1. 알림 제공자가 APNS에 요청 전송 (device token + payload)
2. APNS가 푸시 알림을 iOS 기기로 전달 |
Android 푸시 알림 | - 알림 제공자 - FCM (Firebase Cloud Messaging) - Android 단말 |
1. 알림 제공자가 FCM에 요청 전송 (device token + payload) 2.FCM가 푸시 알림을 Androind 기기로 전달 |
SMS 메시지 | - 외부 SMS 게이트웨이 (예: Twilio, Nexmo) |
- 전화번호 기반으로 문자 발송 - 비용 발생 (건당 과금) |
이메일 | - 외부 이메일 서비스 (예: SendGrid, Mailchimp) |
- SMTP API 또는 HTTP API로 발송
- 발송 성공률 높음, 분석 기능 제공 - 발송량에 따라 비용 발생 |
연락처 정보 수집 절차
- 사용자별 연락처 정보를 1:N 매핑으로 저장함
수집 시점
시점 | 설명 |
앱 첫 설치 |
FCM/APNS 토큰 발급 후 → 서버에 전송
|
회원 가입 | 전화번호 / 이메일 주소 입력 시 수집 |
단말 추가 로그인 |
새로운 device token 수집 → device 테이블에 추가 등록
|
설계 고려사항
항목 | 이유 |
단말 다중 등록 허용 |
사용자가 여러 기기 보유 가능 (휴대폰, 태블릿, PC 등)
|
푸시 알림 동기 전송 필요 |
하나의 알림이 사용자 소유 모든 기기로 전송되어야 함
|
device_token 갱신 로직 |
앱 재설치/토큰 만료 시 갱신 필요 (FCM/APNS가 주기적으로 변경 가능)
|
이메일/전화번호 필수 여부 |
SMS/이메일 알림 전송을 위해 필요.
일부 서비스는 로그인 시 선택 수집 |
3. 초안
구성 요소 | 정의 | 설명 / 예시 / 동작 순서 |
1~N 서비스 | 알림을 요청하는 주체 |
마이크로서비스 or 크론잡 가능
(예: 과금 시스템, 배송 시스템, 예약 시스템 등) |
알림 시스템 | 알림 전송의 중심 허브 |
1. 알림 요청 수신
2. payload 생성 3. 전송 채널 선택 및 전달 |
3rd-Party 서비스 | 실제 알림을 사용자에게 보내는 외부 채널 |
⚠️ 지역/서비스 특성에 따라 대체 가능해야 함
(예: FCM, APNS, Twilio, SendGrid 등) |
사용자 단말 |
최종 수신 기기
|
iOS / Android / SMS / Email
|
문제점
문제점 | 설명 | |
SPOF (단일 장애점) | 알림 시스템 서버가 1개뿐 |
해당 노드 장애 시 전체 알림 기능 중단
|
상태 보관 없음 | 알림 요청 실패 시 전송 이력 유실 |
재시도 불가
|
성능 병목 가능성 | 비용 큰 작업들이 동기적 처리 |
- 알림 준비 (paging, HTML 생성)
- 3rd-party 호출 - 응답 대기 |
3rd-party 서비스 종속성 |
특정 서비스가 지역에서 작동하지 않으면 시스템 전체 다운
|
|
4. 개선
- 3rd-party service별 메시지 큐 도입: 알림 채널별로 큐를 분리
- 작업 서버 분리 배치: 채널별 비동기 처리 전용 워커 운영
해결
초안의 문제 | 개선 방식 | 해결 결과 |
SPOF | 알림 시스템 scale-out | |
상태 보관 없음 | 채널별 큐 도입 | 전송 실패 이력 상태 추적 재시도 처리 가능 (백오프 전략, 재시도 횟수 제한) |
성능 병목 가능성 | 채널별 큐 + 워커 도입 | 무거운 작업이 기기별로 격리됨 → 전체 사용자 응답 빠름 + I/O 병목 최소화 |
3rd-party 서비스 종속성 | 채널별 큐 + 워커 도입 | 외부 서비스 에러가 기기별로 격리됨 |
5. 상세 설계
안정성
항목 | 설명 | 해결 방법 |
데이터 손실 방지 | 알림 자체가 사라지는 건 치명적 (알림이 지연되거나 순서가 바뀌는 건 괜찮음) |
- Outbox 패턴 (알림 요청을 DB에 저장)
- 실패 시 재시도 매커니즘 구현 |
알림 중복 전송 방지 | 같은 알림이 두 번 이상 전송될 수 있음 (네트워크 재시도, 중간 장애 등) |
- 알림에 고유 ID(이벤트 ID) 부여
- 전송 전 DB나 캐시에 전송 여부 검사 - 전송 이력 저장 후 중복 요청 무시 처리 |
추가 컴포넌트
항목 | 설명 | 구현 방식 / 고려 포인트 |
알림 템플릿 | 알림 메시지 형식을 일관되게 유지 |
- 템플릿 ID 기반 메시지 구성
- 변수만 바꿔 채움 (ex: {{userName}}님, 배송이 출발했어요) |
알림 설정 | 사용자별 수신 여부 설정 |
- 사용자 ID 기준 일대다 테이블 구성
- 알림 유형별 ON/OFF 상태 저장 (ex: push: ON, email: OFF) |
전송률 제한 | 동일 사용자에게 너무 많은 알림 발송 방지 |
- 사용자·시간 단위 rate limit 적용
- 초당/분당/일간 전송 횟수 제어 (Redis) |
이벤트 추적 | 알림 전송 상태/결과 추적 |
- 이벤트 로그 전송 (Kafka)
- 분석 시스템으로 수집 후 대시보드 구성 (BigQuery, ClickHouse) |
시스템 모니터링 | 시스템 가용성 및 장애 감지 |
- 실시간 모니터링 (CPU, 큐 길이, 에러율 등)
- Alertmanager 연동 알람 발송 |
'Code' 카테고리의 다른 글
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 12. 채팅 시스템 설계 (3) | 2025.08.03 |
---|---|
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 6. 키-값 저장소 설계 (3) | 2025.08.02 |
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 2. 개략적인 규모 추정 (3) | 2025.08.01 |
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 1. 사용자 수에 따른 규모 확장성 (2) | 2025.07.31 |
[도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지] 10. 이벤트 (0) | 2025.06.20 |