1단계 문제 이해 및 설계 범위 확정
요즘 Application은 뉴스, 제품 업데이트, 이벤트 등 다양한 정보를 유저에게 비동기적으로 제공한다. 알림 시스템은 모바일 푸시 알림에 한정되지 않는다. 알림 시스템은 기본적으로 모바일 Push 알림, SMS 메세지, 이메일의 세 가지로 분류할 수 있다.
하루 백만 건 이상의 알림을 처리하는 높은 확장성 있는 시스템을 구축하는 것은 쉬운 일이 아니다.
책에서는 다음과 같은 요구사항을 정의하고 있다.
- 모바일 Push 알림 / 이메일 / SMS 모두 지원
- 연성 실시간(실시간이지만, 어느 정도 지연은 허용)
- IOS / Android / Desktop / Laptop 모두 지원
- 알림 생성의 주체는, 프로그램이 생성할 수도 있고 스케줄링 작업으로 처리할 수도 있다.
- 하루 천만 건의 모바일 Push 알림 / 백만 건의 SMS 메세지 / 5백만 건의 이메일
2단계 개략적 설계안 제시 및 동의 구하기
각 시스템 별 개략적 설계안은 다음과 같다. 기본적으로는 다음과 같은 내용을 다룬다.
- 알림 유형별 지원 방안
- 연락처 정보 수집 절차
- 알림 전송 및 수신 절차
알림 유형별 지원 방안
iOS 푸시 알림
ios 푸시 알림을 보내기 위해서는 세 가지 컴포넌트가 필요하다.
- 알림 제공자(Provider): 알림 요청을 만들어, Apple Push 알림 서비스로 보내는 주체다. 알림 요청을 보내기 위해서는 다음과 같은 데이터가 필요하다.
- 단말 토큰 : 알림 요청을 보내기 위한 고유 식별자
- 페이로드 : 알림 내용을 담은 JSON Dictionary다.
- APNS : 애플이 제공하는 원격 서비스로, 푸시 알림을 기기로 보내는 역할을 담당한다.
- iOS 단말
안드로이드 푸시 알림
안드로이드 푸시 알람도 비슷하다. APNS 대신 FCM을 사용한다는 점만 다르다.
SMS 메세지
SMS 메세지는 보통 트윌리오, 넥스모 같은 제3자 서비스를 이용한다.
이메일
고유 이메일 서버를 구축할 역랑은 갖추고 있으나, 대부분은 이메일 서비스를 사용한다.
연락처 정보 수집 절차
알림 전송을 위해서는 단말 토큰, 전화번호 등 개인 정보 수집 절차가 필요하다.
알림 전송 및 수신 절차
다음은 위 절차를 고려한 설계 초안이다.
- 1부터 N까지의 서비스 : MSA일 수도 있고, 크론 잡일수도 있고 시스템 분산 컴포넌트일 수도 있다.
- 알림 시스템 : 알림 전송/수신 처리의 핵심이다. 우선은 1개 서버만 사용하는 시스템이라고 가정해보면, 각 서버에 알림 전송을 위한 API와 제3자 서비스에 전달할 페이로드를 생성할 수 있어야 한다.
- 제3자 서비스 : 사용자에게 실제로 알림을 전달하는 역할을 한다. 제3자 서비스와의 통합을 진행할 때 유의할 점은 확장성이다. 쉽게 새 서비스를 통합하거나, 기존 서비스를 제거할 수 있어야 한다. 그리고 특정 서비스를 사용할 수 없는 시장도 존재하는 것을 고려해야 한다. FCM은 중국에서 사용할 수 없어 Jpush같은 서비스를 사용해야 한다.
- iOS, 안드로이드, SMS, 이메일 단말: 사용자는 자기 단말에서 알림을 수신한다.
위 서비스는 몇 가지 문제가 있다.
- SPOF: 알림 서비스 컴포넌트가 위는 하나밖에 없는데 알림 서비스의 장애가 모든 장애로 이어지는 것이다.
- 규모 확장성: 한 대의 서비스로 관리하기 때문에 데이터베이스나 캐시 등 중요 컴포넌트의 규모를 늘리기 어렵다.
- 성능 병목: 알림을 처리하고 보내는 것은 자원이 많이 필요한 작업일 수 있다. 한 번에 많은 처리를 하면 시스템이 과부하 상태에 걸릴 수 있다.
개략적 설계안(개선)
- 데이터베이스와 캐시를 알림 시스템의 주 서버에서 분리한다.
- 알림 서버를 증설하고 자동으로 수평 규모 확장이 이루어 질 수 있도록 한다.
- 메세지 큐를 이용해, 시스템 컴포넌트 사이의 강한 결합을 끊는다.
- 1부터 N 까지의 서비스
- 알림 서버 : 다음 기능을 제공한다.
- 알림 전송 API : 스팸 방지를 위해, 사내 서비스 또는 인증된 클라이언트만 이용 가능하다.
- 알림 검증 : 이메일 주소, 전화번호 등에 기본적 검증을 수행한다.
- 데이터베이스 또는 캐시 질의 : 알림에 포함시킬 데이터를 가져오는 기능
- 알림 전송 : 알림 데이터를 메세지 큐에 넣는다. 하나 이상의 큐를 사용해 병렬적으로 목적에 맞게 사용한다.
- 캐시 정보: 사용자 정보, 단말 정보, 템플릿 등을 캐시한다.
- 데이터베이스: 사용자, 알림, 정보 등을 저장
- 메세지 큐 : 각 컴포넌트 간 의존성을 줄이기 위해 사용한다. 다양한 알림이 전송될 때 버퍼 역할을 위해서도 사용된다. 목적에 맞게 큐를 사용하기 때문에 하나에서 장애가 발생해도 다른 큐는 독립적으로 작동한다.
- 작업 서버: 큐에서 알림을 꺼내 제3자 에게 전송한다.
- 제3자 서비스
- 단말
3단계 상세 설계
상세 설계 단계에서 추가적으로 살펴봐야할 것은 다음과 같다.
- 안정성
- 추가 컴포넌트 및 고려사항: 템플릿 / 알림 설정 / 전송률 제한 / 재시도 매커니즘 / 보안 / 큐 모니터링 등
- 개선된 설계안
안정성
- 데이터 손실 방지
알림 시스템은 데이터 손실 방지를 위해, 데이터를 데이터베이스에 보관하고 재시도 매커니즘을 구현해야 한다. 알림 로그 데이터베이스를 유지하는 것이 한 가지 방법이다.
- 알림 중복 전송 방지
분산 시스템 특성 상 가끔은 같은 알림이 중복되어 전송될 수도 있다. 중복 탐지 매커니즘을 도입하고, 오류를 신중하게 처리해야 한다.
예를 들면, 보내야 할 알림이 도착하면 이벤트 ID를 검사하여 이전에 본 적이 있다면 버리고 그렇지 않다면 발송하는 식이다.
추가 필요 컴포넌트 및 고려사항
- 알림 템플릿
대부분의 템플릿은 형식이 비슷하다. 알림 템플릿은 이런 유사성을 고려하여, 메세지의 모든 부분을 처음부터 다시 만들 필요가 없도록 해준다. 인자나 추적 링크를 조정하는 식으로 지정한 형식으로 맞춰 알림을 만들어낸다.
- 알림 설정
알림을 받을 것인지 아닌지 등 사용자가 알림 설정을 커스텀할 수 있는 것이 사용성이 좋다.
- 전송률 제한
한 사용자가 받을 수 있는 알림 빈도를 제한하는 식으로 특정 사용자에게 너무 많은 알림이 가지 않게 조절할 수 있다.
- 재시도 방법
제3자 서비스가 알림 발송에 실패하면, 알림을 재시도 전용 큐에 넣고 계속해서 같은 문제가 발생하면 서드파티 제공 사에 문의한다.
- 푸시 알람과 보안
iOS와 안드로이드의 경우 appKey나 appSecret을 통해 전송을 가능하게 하여 보안을 지킨다.
- 큐 모니터링
큐의 메트릭 정보를 수집하여 작업 서버의 현황을 파악해 적절한 조치를 취하는 것이 좋다.
- 이벤트 추적
알림 확인율 / 클릭율 / 실제 앱 사용으로 이어지는 비율 같은 메트릭을 취합해 데이터를 분석하여 적절하게 알림 시스템을 수정할 수 있어야 한다.
최종 설계
- 알림 서버에 인증과 전송률 제한이 추가 됐다.
- 실패에 대응하기 위한 재시도 기능이 추가 됐다.
- 템플릿을 사용하여 생성 과정을 축약하고, 일관성을 유지한다.
- 모니터링과 추적 시스템을 추가하여 시스템 상태를 확인하고 시스템 개선하기 쉽도록 파악한다.
4단계 마무리
추가적으로 살펴볼 것은,
- 안정성
- 보안
- 이벤츠 추적 및 모니터링
- 사용자 설정
- 전송률 제한
정도가 있다.
개인적으로 컴포넌트 간 의존성을 줄이기 위해, 큐를 사용한다는 안에는 동의 하지만.. 일종의 오버헤드가 아닌가 하는 생각이 든다. 이정도로 복잡하게 태스크를 구축해서 관리할 정도의 알림 서비스가 세상에 얼마나 있을까란 생각도 들고, 또 알림 서비스 특성 상 지연이나 일종의 장애가 발생해도 시스템에 큰 영향을 미치지 않는 경우가 많기 때문에.. 과도한 리소스 사용을 지양해야 한다고 생각한다.
또 책에서 깊게 다루지는 않았는데, 대용량 트래픽은 곳 글로벌 서비스와 연결되기 때문에 살펴봐야 하는게 국가별 정책이 이런 대용량 처리를 위한 설계보다 더 중요할 수도 있다.
예를 들면, 미국의 경우 10DLC 라고 하여 미국 현지 전화번호가 없으면 아예 미국으로 SMS를 발송할 수 없도록 되어있다. 막연히 리소스 관리의 편의성을 위해 AWS SMS 기능을 이용한다면, 10 DLC를 발급하는데 오랜시간이 걸리거나 최종적으로 발급받지 못하여 고생할 수도 있다.
유럽의 GDPR이나 중국의 기준을 충족하지 못하면 개인정보 수집이나 알람 발송 자체가 불가능 할 수도 있다. 서드파티 벤더사를 찾을 때 어떤 나라를 지원하고, 어떤 템플릿 형태까지 지원하고 어떤 제약이 있는지 꼼꼼히 살펴보고 서비스에 도입하는 것이 매우 중요하다.
먼 훗날… 서비스에 이미 도입된 상태에서 개선하려고 한다면 큰 비용이기 때문에.. 사전에 알아보자!
Share article