알림 시스템은 어느 서비스나 항상 고민하게 되는 부분이라 생각한다.
실제로 서비스를 구현할 때, 다양한 고민들을 하게 되는데, 설계에 대한 초점에서 바라본 건 새로웠다.
알림 시스템
- 고객에게 중요할 만한 정보를 비동기적으로 전송
- 모바일 푸시 알림, SMS 메시지, 이메일 세 가지로 분류
1단계 : 문제 이해 및 설계 범위 확정
- 시스템이 지원하는 알림 종류
- 푸시 알림, SMS 메시지, 이메일
- 실시간 시스템 여부
- 연성 실시간 시스템이라고 가정 (시스템 부하 시 약간의 지연 무방)
- 지원해야 하는 종류의 단말
- iOS, 안드로이드, 랩톱/데스크톱
- 알림을 만들 수 있는 주체
- 클라이언트 애플리케이션 or 서버 측의 스케줄링
- 알림을 받지 않도록 설정도 가능해야 함
- 하루에 보낼 수 있어야 하는 양
- 천만 건의 모바일 푸시 알림, 백만 건의 SMS 메시지, 5백만 건의 이메일
2단계 : 개략적 설계안 제시 및 동의 구하기
알림 유형별 지원 방안
iOS 푸시 알림
- 알림 제공자
- 알림 요청을 만들어 애플 푸시 알림 서비스(APNS)로 보내는 주체
- 단말 토큰(고유 식별자), 페이로드(알림 내용을 담은 JSON 딕셔너리) 데이터가 필요
- APNS
- 애플이 제공하는 원격 서비스
- 푸시 알림을 iOS 장치로 보내는 역할을 담당
- iOS 단말
- 푸시 알림을 수신하는 사용자 단말
안드로이드 푸시 알림
- iOS 와 비슷한 절차이며 APNS 대신 FCM(Firebase Cloud Messaging)을 사용하는 점이 다름
SMS 메시지
- 보통 트윌리오, 넥스모 같은 제3 사업자의 서비스를 많이 이용
- 사용 서비스라 이용요금 필요
이메일
- 대부분의 회사가 고유 이메일 서버를 구축할 수 있지만 사용 이메일 서비스 많이 이용
- 센드그리드, 메일침프 등 (높은 전송 성공률, 데이터 분석 서비스)
연락처 정보 수집 절차
- 사용자가 앱 설치, 계정 등록 등을 하면 API 서버는 해당 사용자의 정보를 수집하여 데이터 베이스에 저장
- 이메일 주소와 전화번호는 user 테이블에 저장
- 단말 토큰은 device 테이블에 저장 (한 사용자가 여러 단말을 가질 수 있으므로)
알림 전송 및 수신 절차
개략적 설계안 (초안)
- 1부터 N까지의 서비스
- 서비스 각각은 마이크로서비스, 크론잡, 분산 시스템 컴포넌트 등 일 수 있음
- 알림 시스템
- 알림 전송/수신 처리의 핵심
- 초안 설계안에선 1개 서버만 사용하는 시스템으로 가정
- 제3자 서비스
- 사용자에게 알림을 실제로 전달하는 역할
- 통합 진행 시 확장성을 유의해야 함 (새로운 서비스 통합 or 기존 서비스 제거 등등 ...)
- 사용자는 자기 단말에서 알림을 수신
- 초안 설계안의 몇 가지 문제
- SPOF (알림 서비스에 서버가 하나밖에 없으므로)
- 규모 확장성 (한 대 서버이므로)
- 성능 병목 (알림을 처리하고 보내는 것은 자원을 많이 필요로 함, 시스템 과부하 상태에 빠질 수도 있음)
개략적 설계안 (개선된 버전)
- 개선 방향
- 데이터베이스와 캐시를 알림 시스템의 주 서버에서 분리
- 알림 서버를 증설하고 자동으로 수평적 규모 확장이 이루어질 수 있도록 함
- 메시지 큐를 이용해 시스템 컴포넌트 사이의 강한 결합을 끊음
- 알림 서버가 제공하는 기능
- 알림 전송 API (사내 서비스, 인증된 클라이언트)
- 알림 검증
- 데이터베이스 또는 캐시 질의
- 알림 전송 (메시지 큐에 알림 데이터를 넣음)
- 캐시
- 사용자 정보, 단말 정보, 알림 템플릿 등을 캐시 함
- 데이터베이스 (DB)
- 사용자, 알림, 설정 등 다양한 정보를 저장
- 메시지 큐
- 시스템 컴포넌트 간 의존성을 제거하기 위해 사용
- 다량의 알림이 전송되어야 할 경우를 대비해 버퍼 역할도 수행
- 알림의 종류별로 별도 메시지 큐를 사용
- 작업 서버
- 메시지 큐에서 전송할 알림을 꺼내서 제3자 서비스로 전달하는 역할을 담당하는 서버
- 알림 전송 과정
- API를 호출하여 알림 서버로 알림을 보냄
- 알림 서버는 메타데이터를 캐시나 DB에서 가져옴
- 알림 서버는 전송할 알림에 맞는 이벤트를 만들어서 해당 이벤트를 위한 큐에 넣음
- 작업 서버는 메시지 큐에서 알림 이벤트를 꺼냄
- 작업 서버는 알림을 제3자 서비스로 보냄
- 제3자 서비스는 사용자 단말로 알림을 전송
3단계 : 상세 설계
안정성
데이터 손실 방지
- 어떤 상황에서도 알림이 소실되면 안 됨
- 지연이나 순서가 틀리는 것보다 심각함
- 알림 데이터를 DB에 보고하고 재시도 메커니즘 구현 필요
알림 중복 전송 방지
- 완전히 막는 것은 불가능
- 중복을 탐지하는 메커니즘 도입
- 오류를 신중히 처리
- 보내야 할 알림의 이벤트 ID를 검사하여 본 적이 있는 이벤트인지 살펴봄
추가로 필요한 컴포넌트 및 고려 사항
알림 템플릿
- 알림의 유사성을 고려하여 알림 메시지의 모든 부분을 다시 만들 필요를 덜어줌
- 인자, 스타일, 추적 링크를 조정하여 알림을 만들어 내는 틀
- 일관성 유지 및 오류를 줄이고 알림 작성 시간 감소
알림 설정
- 알림 설정 테이블에 보관
- user id, channel, 해당 채널로 알림을 받을 것인지 등의 정보 저장
- 특정 종류의 알림을 보내기 전에 해당 정보를 조회
전송률 제한
- 한 사용자가 받을 수 있는 알림의 빈도 제한
- 알림을 너무 많이 보내면 클라이언트가 알림을 끌 수 있으므로 제한
재시도 방법
- 알림 전송에 실패 시 해당 알림을 재시도 전용 큐에 넣음
- 같은 문제가 계속해서 발생하면 개발자에게 통지
푸시 알림과 보안
- iOS와 안드로이드 앱의 경우 알림 전송 API는 appKey와 appSecret을 사용하여 보안 유지
- 인증되거나 승인된 클라이언트만 알림을 보낼 수 있음
큐 모니터링
- 큐에 쌓인 알림의 개수는 알림 시스템 모니터링의 중요한 메트릭
- 이 수가 너무 크면 작업 서버들이 이벤트를 빠르게 처리하지 못한 것 -> 서버 증설 필요
이벤트 추적
- 알림 확인율, 클릭률, 실제 앱 사용 등의 비율 같은 메트릭은 사용자를 이해하는데 중요
- 보통은 알림 시스템은 데이터 분석 서비스와도 통합해야만 함
수정된 설계안
- 알림 서버에 인증과 전송률 제한 기능 추가
- 전송 실패에 대응하기 위한 재시도 기능도 추가 (다시 큐에 넣고 지정된 횟수만큼 재시도)
- 전송 템플릿을 사용하여 알림 생성 과정을 단순화하고 알림 내용의 일관성을 유지
- 모니터링과 추적 시스템을 추가
4단계 : 마무리
- 알림 필수불가결한 기능
- 메시지 큐를 적극적으로 사용하여 시스템 컴포넌트 사이의 결합도를 낮출 것
- 최적화 기법
- 안정성
- 보안
- 이벤트 추적 및 모니터링
- 사용자 설정
- 전송률 제한
반응형
'🏛️ Architecture' 카테고리의 다른 글
마이크로서비스 아키텍처 구축 CH.4 마이크로서비스 통신 방식 (0) | 2023.11.04 |
---|---|
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 11장 뉴스 피드 시스템 설계 (0) | 2023.03.19 |
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] 9장 웹 크롤러 설계 (3) | 2023.03.12 |
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] Chapter 8 URL 단축기 설계 (2) | 2023.03.07 |
[가상 면접 사례로 배우는 대규모 시스템 설계 기초] Chapter 7. 분산 시스템을 위한 유일한 ID 생성기 (2) | 2023.03.02 |