-
[알림 서비스] 전체 구성 설계STOVE DEVCAMP 3기/알림 서비스 2023. 3. 10. 01:57
💡 참고
대규모 시스템 설계 책
📌 요구사항
모바일 푸시 알림만 지원함 (SMS, 이메일 알림 X)
연성 실시간 시스템임
- 알림은 가능한 빨리 전달되어야 하지만 시스템에 높은 부하가 걸렸을 때 약간의 지연은 무방함
약간의 지연은 무방하지만 어떤 상황에서도 알림이 소실되면 안됨 → 데이터 손실 방지를 보장해줘야 함
iOS, 안드로이드 단말 모두 지원함
알림으로 전송할 모든 이벤트는 클라이언트에서 만들어 냄
디바이스별 푸시 알림 ON/OFF 설정 가능함
하루에 1000건(100명의 사용자 x 10건의 알림)의 모바일 푸시 알림을 보낼 수 있어야 함
사용자별 알림 목록 조회가 가능함
- 현재까지 받은 알림 전체 다 볼 수 있는 건가?
- 비즈니스 요구사항이므로 팀원들과 함께 정할 필요 있음
- ex) 30일 치의 알림만 보여주기
단건 알림과 다중 알림 모두 가능함
- 다중 알림 : 1개의 이벤트 발생 시 n명의 유저에게 동시에 알림을 전송함
1명의 유저는 여러 개의 FCM 등록 토큰을 가질 수 있음
- ex) A 사용자가 아이폰, 아이패드로 각각 로그인한 경우 A 사용자에게 전달되는 알림은 아이폰과 아이패드 모두에 보내져야 함
로그아웃, 탈퇴한 유저에게는 알림을 전송하지 않음
- 해당 유저의 모든 디바이스에 적용됨
디바이스는 고유한 FCM 등록 토큰을 가짐
앱이 foreground/background일 때 모두 알림을 수신해야 함
- 앱이 background 상태일 때는 외부 Push 알림을 주고, foreground 상태일 때는 화면상 알림을 띄움
*이후 적용해볼 조건
알림 데이터는 모두 다 쌓아둘 필요 없으므로, 일정 시간 이후 삭제되도록 구성한다.
비활성 디바이스의 토큰을 삭제한다.
- 토큰 timestamp가 일정 기간 이상 갱신되지 않았을 때
✅ 서비스 기능 목록
- FCM 토큰 등록 및 타임스탬프 업데이트
- FCM 토큰 삭제
- 알림 생성
- 알림 목록 조회
- PUSH 알림 ON/OFF 설정
📌 요구사항 만족을 위한 상세 설계안
데이터 손실 방지
- 알림 데이터를 데이터베이스에 저장함 - 반영 완료
- 알림 전송 재시도 메커니즘을 구현함 - 코드 작성하며 구현 예정
재시도 방법
- 제3자 서비스가 알림 전송에 실패하면, 해당 알림을 재시도 전용 큐에 넣고 지정된 횟수만큼 재시도함
- 동일한 문제 계속해서 발생하면 개발자에게 통지함
앱 상태(fore/background)에 따른 알림 표시
- FCM 서버가 보낸 Push 수신 시 디바이스의 fore/back 상태에 따라 다르게 알림을 띄워주도록 함
- 참고
📌 1차 설계안 - 현재 상황
*알림 서버 역할 (클루터에서의 기능 한정)
- 푸시 토큰 관리
- FCM 토큰 등록 및 타임스탬프 업데이트
- 탈퇴 유저의 FCM 토큰 삭제
- 만료 토큰 삭제
- 알림 생성 API 제공
- 유저/트윗 서비스에서의 이벤트 발생 시 알림을 생성할 수 있도록 API를 제공함
- 알림 데이터 저장
- 알림 목록 조회를 위한 알림 DB 질의
- 디바이스별 푸시 알림 ON/OFF 설정 저장
- FCM에 알림 전송
- FCM 장애나 전송 오류 시 알아서 failover 및 전송 재시도 수행
*알림 DB 역할
- 유저의 디바이스 단말 토큰 저장
- 유저의 알림 데이터 저장
*해당 설계의 문제점
- SPOF(Single-Point-Of-Failure)
- 1대의 알림 서비스의 서버로 처리하면 해당 서버에 장애 발생 시 전체 서비스의 장애로 이어질 수 있음
- 개선
- 알림 서버 scale-out
- 성능 병목
- 알림 처리하고 제3자의 서버에 보내는 것은 자원을 많이 필요로 하는 작업일 수 있음
- ex) HTML 페이지를 구성해 제3자 서비스의 응답을 기다림
- 따라서 모든 기능을 한 서버로 처리하면 사용자 트래픽이 몰리는 시간에는 시스템이 과부하 상태에 빠질 수 있음
- 알림 처리하고 제3자의 서버에 보내는 것은 자원을 많이 필요로 하는 작업일 수 있음
📌 2차 설계안 - 이후 개선 고려
A. 제3자 제공서비스가 1개
*알림 서버 역할 - 1차 설계안 이후 추가된 역할만 기술함
- 메시지 큐에 알림 전송
- 알림 데이터를 메시지 큐에 넣음
- FCM과의 통신 역할 수행 X
*메시지 큐 역할
- 시스템 컴포넌트 간 의존성 제거
- 다량의 알림이 전송되어야 하는 경우를 대비한 버퍼 역할
*작업 서버 역할
- 메시지 큐에서 전송할 알림을 꺼내 FCM에 전달하는 역할 담당
- FCM 장애나 전송 오류 시 알아서 failover 및 전송 재시도 수행
*시스템 컴포넌트들 간의 협력 과정
- 유저/트윗 서비스가 알림 생성 API를 호출해 알림 서버로 알림 데이터 전송함
- 알림 서버는
- 알림 데이터를 데이터베이스에 저장
- 알림 수신 유저의 디바이스 단말 토큰을 데이터베이스에서 가져옴
- 알림 서버는 알림 이벤트를 만들어 메시지 큐에 넣음
- 작업 서버는 메시지 큐에서 알림 이벤트를 꺼냄
- 작업 서버는 알림을 FCM에 보냄
- FCM은 유저 디바이스 단말로 알림을 전송함
B. 제3자 제공서비스가 n개
- 제3자 제공서비스 별 메시지 큐를 사용하므로 알림을 병렬적으로 처리 가능함
C. 작업 서버에 코어 로직 수행 역할 부여 - 참고
- 많은 트래픽 발생 시에도 안정적으로 지원하도록 하기 위함
- 각 구성요소에 일시 장애가 나더라도 받은 요청은 모두 수행할 수 있도록 하기 위한 구조임
- 추후 채팅 알림이 추가되는 경우를 고려함
- 알림 서비스 내에서 발생하는 모든 작업은 '작업 큐'를 통해 관리하도록 함
*알림 서버 역할
- 많은 트래픽을 우선 받아내는 것이 목적이므로, 간단한 역할만 수행하고 바로 Job을 생성해 작업 큐로 넘김
*메시지 큐 역할
- 알림 서비스에서 발생하는 모든 작업은 해당 큐에서 관리됨
*작업 서버 역할
- 알림 서비스의 코어 로직을 수행함
- 알림 DB와 FCM과 직접적으로 통신함
📌 이후에 추가로 고려해볼 사항 - 대규모 시스템 설계를 위한 확장 사항
알림 중복 전송 방지
- 중복 전송을 100% 방지하는 것은 불가함 - 참고
- 분산 시스템의 경우 같은 알림이 중복되어 전송되기도 하는데, 그 빈도를 줄이려면 중복을 탐지하는 메커니즘을 도입할 수 있음
알림 템플릿 사용
푸시 알림과 보안
- 예시
-
- 알림 전송 API는 appKey와 appSecret을 사용해 보안을 유지함
- 따라서 인증된, 승인된 클라이언트만 해당 API를 사용해 알림을 보내도록 함
큐 모니터링
- 알림 시스템을 모니터링 할 때 중요한 메트릭 중 하나는 큐에 쌓인 알림의 개수임
- 쌓인 알림 개수가 너무 많으면, 작업 서버들이 이벤트를 빠르게 처리하지 못하는 것이므로, 작업 서버 증설을 고려해볼 수 있음
이벤트 추적
- 알림 확인율, 클릭율, 실제 앱 사용으로 이어지는 비율 같은 메트릭은 사용자를 이해하는데 중요함
- 데이터 분석 서비스(analytics)는 보통 이벤트 추적 기능도 제공함
📌 3차 설계안 - 대규모 시스템 설계를 위한 확장 설계안
- 위의 추가로 고려해볼 사항이 적용된 설계안임
- 보안 및 전송률 제한
- 알림 서버에 알림 전송 API 호출 클라이언트에 대한 인증(authentication)과 전송률 제한(rate-limiting) 기능 추가함
- 알림 전송 템플릿을 사용해 알림 생성 과정을 단순화하고 알림 내용의 일관성을 유지함
- 이벤트 추적 및 모니터링
- 알림이 만들어진 후 성공적으로 전송되기까지의 과정을 추적하고 시스템 상태를 모니터링하기 위해 알림 전송의 각 단계마다 이벤트를 추적하고 모니터링할 수 있는 시스템을 통합함 (데이터 분석 서비스)
- 모니터링과 추적 시스템을 추가해 시스템 상태를 확인할 수 있도록 함
'STOVE DEVCAMP 3기 > 알림 서비스' 카테고리의 다른 글
[알림 서비스] 알림 서비스 구조 개선 - 알림 전송 외부 라이브러리 의존성 분리 리팩토링 (0) 2023.03.10 [알림 서비스] 알림 서비스 구조 개선 - 신뢰성 있는 알림 서비스 제공 (0) 2023.03.10 [알림 서비스] 알림 서비스 데이터베이스 설계 (0) 2023.03.10 [개념] MongoDB 알고 사용하기 - 데이터 모델링 (0) 2023.03.10 [개념] MongoDB 알고 사용하기 (0) 2023.03.10