CASE · INTERMEDIATE읽기 22분검토일 2026-08-29
알림 시스템
설계
알림은 메시지를 많이 보내는 문제가 아닙니다. 사용자의 의도·동의·현재 시간과 채널의 실패 제약을 함께 반영해, 중요한 사건을 중복 없이 전달하는 문제입니다.
운영자 직접 작성·기술 검토·최종 검토 2026.08.29
개념 이해정책 설계장애 대응운영 관점진도 저장
!30초 핵심 요약
공급자 수락, 기기 표시 가능 신호, 사용자 열람은 서로 다른 배송 사건입니다. intent를 정본으로 두고 timeout 재시도에도 사용자에게 같은 알림 카드가 중복 표시되지 않게 합니다.
입력 경계Intent + Idempotency
정책 경계Preference at send time
성공 의미Provider ≠ user seen
DESIGN DECISION · 설계 판단
공급자 수락·기기 표시·사용자 열람을 어떤 상태로 구분할 것인가?
예시 알림 의도
1,200만/day
설계 가정
예시 피크 생성
약 1,670 intents/s
계산 결과
예시 채널 fan-out
평균 1.4개
설계 가정
최종 선택
Intent 중심 다단계 배송 사건 + 전송 직전 정책 확인
provider accepted, 가능한 device receipt, opened, inbox read를 별도 상태와 시각으로 기록합니다. 예약·마케팅 알림은 전송 직전에 동의와 조용한 시간을 다시 확인합니다.
선택 이유
- 공급자 성공률을 사용자 도달률로 과장하지 않습니다.
- 기기 오프라인·권한 거부·앱 문제를 공급자 장애와 구분할 수 있습니다.
- timeout 재시도에도 안정된 intent ID로 사용자 중복 노출을 제한합니다.
포기한 대안
provider accepted를 delivered로 확정
운영체제 권한·집중 모드·오프라인 상태 때문에 공급자 수락 뒤에도 사용자 화면 표시와 열람은 확인되지 않을 수 있습니다.
감수한 단점
- 채널마다 제공하는 receipt 수준이 달라 공통 상태가 부분적입니다.
- 전송 직전 정책 조회는 지연과 의존성을 추가합니다.
- opened는 알림 품질의 대리 지표일 뿐 사용자 만족을 직접 증명하지 않습니다.
01 · REQUIREMENTS
누구에게, 어떤 이유로, 언제 보낼지 분리한다
# 요구사항수신자가 같은 메시지를 모든 채널에서 원한다는 가정은 위험합니다. 카테고리와 선호 정책을 먼저 모델링하면 발신 서비스가 공급자·토큰·규제를 직접 알 필요가 없습니다.
R1의도 중심 요청업무 사건과 멱등 키로 intent를 만들고, 채널은 정책이 고릅니다.
R2개인별 선호동의, 조용한 시간, 언어, frequency cap, suppression을 적용합니다.
R3채널 격리APNs/FCM, 이메일, SMS의 속도·실패·자격 증명을 worker로 분리합니다.
R4설명 가능한 결과accepted, suppressed, provider accepted, failed를 하나의 성공으로 합치지 않습니다.
02 · HIGH-LEVEL DESIGN
의도·정책·전달 시도를 다른 수명으로 둔다
# 아키텍처outbox는 업무 트랜잭션과 알림 발행의 틈을 줄이고, 채널 worker는 공급자 장애를 서로 격리합니다. 전달은 at-least-once일 수 있으므로 사용자 노출 중복 방지는 별도 데이터 제약으로 다룹니다.
알림 시스템의 정책과 채널 전달 경로 SVG DIAGRAM · intent / preference / worker / status
중요: 공급자 호출은 성공 응답을 받지 못한 채 실제 수락됐을 수 있습니다. 큐의 at-least-once 재처리는 허용하되, intent_id와 inbox의 고유 제약으로 사용자에게 같은 업무 알림이 여러 번 쌓이지 않게 설계합니다.
03 · REQUEST FLOW
정책 판단과 공급자 수락을 한 단계씩 남긴다
# 요청 흐름실패 뒤에 무엇을 다시 해야 하는지 알려면 intent, 정책 결정, 채널 attempt, 사용자 상호작용을 별도 상태로 기록해야 합니다.
1Intent 기록업무 이벤트와 멱등 키를 API·outbox에 원자적으로 남깁니다.
2선호 평가동의, quiet hours, suppression, cap을 전송 직전에 확인합니다.
3채널 작업endpoint마다 push·email·SMS의 독립 attempt를 예약합니다.
4재시도 분류timeout과 영구 실패를 나누고 backoff·jitter·만료를 적용합니다.
5결과 정규화provider 수락, 실패, inbox 표시, 읽음 신호를 분리해 저장합니다.
04 · TRADEOFFS
도달률을 높이는 선택은 동의·중복·비용을 함께 바꾼다
# 트레이드오프최신 선호를 존중하려면 전송 직전 재검사가 유리하지만, 완벽한 순간 일관성을 약속하지는 않습니다. 어떤 category가 예외인지, 변경 전파를 얼마나 빨리 할지까지 계약으로 정합니다.
| 선택 | 장점 | 제약 | 권장 판단 |
|---|
| Intent + channel worker | 공급자 장애 격리, 재시도·감사 가능 | 상태 모델·운영 구성 증가 | 여러 채널 또는 중요 알림에 기본 구조 |
| enqueue 시 정책 고정 | 낮은 지연, 재현 쉬움 | 나중의 해지·quiet 변경을 놓칠 수 있음 | 즉시성 우선 category만 제한적으로 |
| 전송 직전 재검사 | 현재 동의에 더 가까움 | 예약·cache·순서 복잡도 | 마케팅과 예약 알림의 기본 |
| SMS 자동 fallback | 긴급 도달률 보완 가능 | 단가·중복·동의 위험 | 명시된 severity와 동의가 있을 때만 |
| provider accepted = 성공 | 집계가 단순 | 표시·열람을 과장 | 수락·표시·읽음 지표를 분리 |
05 · FAILURE MODES
여섯 가지 실패를 사용자 영향과 복구 검증으로 다룬다
# 장애 6가지↯outbox 발행 누락
업무는 완료됐지만 알림 intent가 큐로 가지 않아 사용자에게 아무것도 도착하지 않습니다.
대응 · outbox relay 재처리와 업무 이벤트 대비 reconciliation. 기간별 차이를 설명 가능한 수준으로 검증합니다.
2×timeout 뒤 결과 불명
공급자는 수락했지만 worker는 응답을 못 받아 재시도하고, 사용자는 중복을 볼 수 있습니다.
대응 · 멱등 키, attempt 이력, inbox unique 제약. 동일 intent의 노출 수와 중복률을 확인합니다.
⌁push 공급자 장애
APNs/FCM 오류가 backlog를 늘리고 다른 채널 또는 API 수락을 밀어낼 수 있습니다.
대응 · 채널별 queue, circuit breaker, backoff. 복구 뒤 queue age와 drain 속도를 확인합니다.
×만료 endpoint 누적
바뀐 기기 토큰·반송 주소에 계속 시도해 비용과 실패율이 커집니다.
대응 · 영구 실패 분류, endpoint 비활성 후보, 재인증 유도. 비활성 대상 재전송이 0인지 봅니다.
☾선호 변경 전파 지연
사용자가 해지했는데 예약 작업이 오래된 정책을 보고 발송할 수 있습니다.
대응 · 전송 직전 재검사와 version 지표. 변경 뒤 허용/차단 전환 시간이 목표 안인지 확인합니다.
!캠페인 폭주
대량 발송이 보안·거래 알림의 queue와 provider quota를 잠식할 수 있습니다.
대응 · priority queue, quota, 예약 용량. 캠페인 중에도 중요 category의 SLO를 검증합니다.
06 · OPERATIONS
보안·관측·비용을 채널 호출 밖에서 관리한다
# 운영⌾보안과 개인정보기기 토큰·이메일·전화번호·메시지 본문을 로그에서 분리하고, APNs·FCM·SMTP 자격 증명은 비밀 저장소에서 최소 권한으로 주입합니다.
endpoint_id · masking · audit
⌁관측 가능성intent 수락, policy suppression, provider 수락, queue age, retry, invalid endpoint, inbox dedupe를 stage별로 관측합니다.
queue_age · outcome · version
₩비용 모델SMS·email·push 연동 비용뿐 아니라 재시도, endpoint 보관, 템플릿 렌더링, 분석 로그, 수동 반송 대응까지 채널별로 계산합니다.
attempt × channel × retry
면접 모드 · 추가 질문05:00
“하루 1,200만 건의 알림을 푸시·이메일·SMS로 보내야 합니다. 사용자의 해지와 조용한 시간을 지키면서도, 공급자 timeout 뒤 중복을 줄이고 보안 알림이 캠페인에 밀리지 않게 하려면 어떤 데이터 모델·큐·상태 지표를 두겠습니까?”
intent + outboxpreference at sendchannel isolationat-least-once 분리priority SLO
답변 구조 보기 5단계
- 알림 종류를 거래·보안·마케팅으로 나누고, 채널별 동의·조용한 시간·fallback 조건을 먼저 확인한다.
- 업무 서비스가 intent와 outbox를 기록하고 큐로 비동기 전달한다는 기본 경로를 설명한다.
- 선호 오케스트레이터와 채널 worker를 분리해 APNs/FCM, 이메일, SMS의 실패와 quota를 격리한다고 말한다.
- at-least-once 전달과 사용자에게 정확히 한 번 보이는 효과의 차이를 설명한다. idempotency key, attempt 이력, inbox unique 제약을 함께 제시한다.
- 공급자 수락·표시·열람을 구분한 지표와, opt-out·토큰 폐기·캠페인 폭주·provider 장애의 복구 검증을 덧붙인다. 이번 선택: 수락·표시 가능 신호·열람을 서로 다른 배송 사건으로 저장한다. 깨지는 신호: accepted를 delivered로 표시하거나 timeout attempt가 무한 재시도된다. 다음 검증: 오프라인·권한 거부·중복 웹훅을 조합해 상태가 과장되지 않는지 확인한다.
INTERVIEW ↔ PRACTICE · 면접과 실무의 차이
배송 완료 알림의 수락·표시 가능 신호·열람을 분리하기
INTERVIEW · 면접
한 delivered 상태 대신 관찰 가능한 사건을 순서대로 답합니다.
- intent와 채널별 attempt를 분리합니다.
- provider accepted와 opened를 같은 성공으로 합치지 않습니다.
- timeout은 결과 불명으로 두고 중복 표시를 제한합니다.
PRACTICE · 실무
오프라인·권한 거부·중복 콜백을 조합해 상태를 검증합니다.
- accepted와 open의 급격한 차이를 채널별로 관측합니다.
- 오래된 미확정 attempt와 중복 노출률을 추적합니다.
- 전송 직전 opt-out과 quiet hours를 다시 확인합니다.
NEXT CASE STUDY실시간 채팅 시스템 설계
→
EDITORIAL NOTES
작성·검토·참고 자료
- 콘텐츠 원칙
- 이 문서는 독립적으로 재작성한 한국어 학습 자료입니다. 사실과 학습용 설계 가정을 구분합니다.
- 작성·기술 검수
- 프로젝트 운영자가 직접 작성·기술 검토했습니다. 주제별 공식·1차 자료와 명시적인 설계 가정을 확인하며, 독립적인 제3자 검수가 아닙니다. 경력 범위와 검수 원칙 보기
- 최종 검토
- 예상 학습 시간
- 22분
사실 오류·출처 정정은 문의·정정 페이지로 알려 주세요.