본문 바로가기
독서/가상 면접 사례로 배우는 대규모 시스템 설계 기초

10장. 알림 시스템 설계

by yoon_seon 2023. 12. 21.

알림 유형별 지원 방안

알림시스템은 모바일 푸시알림, SMS 메시지, 이메일로 분류할 수 있다.


iOS 푸시 알림

iOS에서 푸시 알림을 보내기 위해서는 세 가지 컴포넌트가 필요하다.

  • 알림 제공자(provider) : 알림 요청을 만들어 애플 푸시 알림 서비스(APNS)로 보내는 주체다. 알림 요청을 만들라면 다음과 같은 데이터가 필요하다.
    • 단말 토큰(device token) : 알림 요청을 보내는 데 필요한 고유 식별자
    • 페이로드(payload) : 알림 내용을 담은 JSON 딕셔너리
  • APNS : 애플이 제공하는 원격 서비스. 푸시 알림을 iOS 장치로 보내는 역할
  • iOS 단말 : 푸시 알림을 수신하는 사용자 단말


안드로이드 푸시 알림

안드로이드 푸시 알림도 iOS와 비슷한 절차로 전송한다. APNS 대신 FCM(Firebase Cloud Messaging)을 사용한다는 점만 다르다.

SMS 메시지

SMS 메시지를 보낼 때는 보통 제3사업자의 서비스를 많이 이용한다.

이메일

이메일 서버를 구축하거나 상용 이메일 서비스를 이용한다.

 

정리를 하자면 다음과 같이 나타낼 수 있다.

연락처 정보 수집 절차

알림을 보내려면 모바일 단말 토큰, 전화번호, 이메일 주소 등의 정보가 필요하다.

사용자가 앱을 설치하거나 회원가입을 하면 API 서버는 사용자의 정보를 수집하여 데이터베이스에 저장한다.

개략적 설계

개략적 설계안(초안)

  • 서비스1 ~ N : 알림을 보내는 서비스
  • 알림 시스템 : 1~N에 알림 전송을 위한 API를 전송하고, 제3자 서비스에 전달할 알림 페이로드를 만들어낼 수 있어야한다.
  • 제3자 제공 서비스 : 사용자에게 알림을 실제로 전달하는 역할
  • iOS, Android, SMS, 이메일 수신 단말 : 알림을 수신하는 단말

하지만 이 설계에는 다음과 같은 문제가 있다.

  • SPOF(Single-Point-Of-Failure) : 알림 서비스 서버가 하나밖에 없어서 서버에 장애가 생기면 전체 서비스의 장애로 이어질 수 있다.
  • 규모 확장성 : 한 대 서비스로 푸시 알림에 관계된 모든 것을 처리 하므로 데이터베이스나 캐시 등 중요 컴포넌트의 규모를 개별적으로 늘릴 방법이 없다.
  • 성능 병목 : 알림을 처리하고 보내는 것은 자원을 많이 필요로 하는데, 한 서버로 모든 것을 처리하면 사용자 트래픽이 많이 몰릴 때 과부하 상태에 빠질 수 있다.


개략적 설계안(개선 버전)

개선할 수 있는 방법

  • 데이터베이스와 캐시를 알림 시스템의 주 서버에서 분리한다.
  • 알림서버를 증설하고 자동으로 수평적 규모 확장이 이루어질 수 있도록 한다.
  • 메시지 큐를 사용해 시스템 컴포넌트 사이의 결합도를 낮춘다.

  • 알림 서버 :
    • 알림 전송 API : 스팸 방지를 위해 인증된 클라이언트만 이용 가능
    • 알림 검증 : 이메일 주소, 전화번호 등에 대한 기본적 검증 수행
    • 데이터베이스 또는 캐시 질의 : 알림에 포함시킬 데이터를 가져오는 기능
    • 알림 전송 : 알림 데이터를 메시지 큐에 넣는다. 따라서 알림을 병렬적으로 처리 가능
  • 캐시 : 사용자 및 단말 정보, 알림 템플릿 등을 캐시할 수 있다.
  • 메시지 큐 : 다량의 알림이 전송되어야 하는 경우를 대비한 버퍼 역할. 알림의 종류별로 별도 메시지큐를 사용하여 제 3자 서비스 가운데 하나에 장애가 발생해도 다른 종류의 알림은 정상 동작한다.
  • 작업 서버 : 메시지 큐에서 전송할 알림을 꺼내서 제3자 서비스로 전달하는 역할을 한다.


개선버전 알림이 전송되는 동작 원리

  1. API를 호출하여 알림 서버로 알림을 보낸다.
  2. 알림 서버는 사용자 정보, 단말 토큰, 알림 설정 같은 메타데이터를 캐시나 데이터베이스에서 가져온다.
  3. 알림 서버는 전송할 알림에 맞는 이벤트를 만들어서 해당 이벤트를 위한 큐에 넣는다.(예를들어 iOS 푸시 알림 이벤트는 iOS 푸시 알림 큐에 넣음)
  4. 작업 서버는 메시지 큐에서 알림 서비스를 꺼낸다.
  5. 작업 서버는 알림을 제3자 서비스로 보낸다.
  6. 제3자 서비스는 사용자 단말로 알림을 전송한다.


알림 시스템 상세 설계하기

안정성

분산 환경에서 운영될 알림 시스템을 설계할 때는 안정성을 확보하기 위해 다음과 같은 것들을 고려할 수 있다.


데이터 손실 방지

알림 전송 시스템에서 알림이 지연되거나 순서가 틀리는 것은 허용가능하더라도 알림 자체가 소실되면 안된다. 이 요구사항을 만족하려면 알림 시스템은 알림 데이터를 데이터베이스에 보관하고 재시도 매커니즘을 구현해야 한다.

 

다음과 같이 알림 로그 데이터베이스를 유지하는 것이 한 가지 방법이다.

알림 중복 전송 방지

같은 알림이 여러 번 반복되는 것을 완전히 막는 것은 불가능하다.

대부분의 경우 알림은 한 번만 전송되겠지만 분산 시스템의 특성상 가끔 같은 알림이 중복되어 전송될 수 있다.

보내야 할 알림이 도착하면 그 이벤트 ID를 검사하여 이전에 본 적이 있는 이벤트인지 살핀 후 중복된 이벤트라면 버리고, 그렇지 않다면 알림을 발송하여 중복을 막을 수 있을 것이다.


추가로 필요한 컴포넌트 및 고려사항

알림 템플릿

대형 알림 시스템은 하루에도 수백만 건 이상의 알림을 처리한다. 알림 메세지의 대부분은 형식이 비슷한데, 알림 템플릿은 이런 유사성을 고려하여 알림 메세지의 모든 부분을 처음부터 다시 만들 필요 없도록 해준다.

템플릿을 사용하면 전송될 알림들의 형식을 일관성 있게 유지할 수 있다.


알림 설정

특정 종류의 알림을 보내기 전에 반드시 해당 사용자가 알림을 켜 두었는지 확인해야 한다.


전송률 제한

사용자에게 너무 많은 알림을 보내지 않도록 하는 방법중 한 가지는 한 사용자가 받을 수 있는 알림의 빈도를 제한하는 것이다. 사용자에게 알림을 너무 많이 보내기 시작하면 사용자가 알림 기능을 꺼버릴 수 있기 때문에 전송률을 제한하는 것은 중요하다.


재시도 방법

제3자 서비스가 알림 전송에 실패하면 해당 알림을 재시도 전용 큐에 넣는다. 같은 문제가 계속해서 발생하면 개발자에게 통지한다.


푸시 알림과 보안

iOS와 안드로이드 앱의 경우, 알림 전송 API는 appKey와 appSecret을 사용하여 보안을 유지한다. 따라서 인증된(authenticated), 혹은 승인된(verified) 클라이언트만 해당 API를 사용하여 알림을 보낼 수 있다.


큐 모니터링

알림 시스템을 모니터링 할 때 중요한 메트릭(metric) 하나는 큐에 쌓인 알림의 개수이다. 이 수가 너무 크면 작업 서버들이 이벤트를 빠르게 처리하고 있지 못하다는 뜻이다. 그런 경우네느 작업 서버를 증설하는게 바람직할 것이다.


이벤트 추적

알림 확인율, 클릭율, 실제 앱 사용으로 이어지는 비율 같은 메트릭은 사용자를 이해하는데 중요하다.

데이터 분석 서비스는 보통 이벤트 추적 기능을 제공하는데 알림시스템을 만들면 데이터 분석 서비스와도 통합해야만한다.

수정된 설계안

  • 알림 서버에 인증과 전송률 제한 기능이 추가되었다.
  • 전송 실패에 대응하기 위한 재시도 기능이 추가되었다. 전송에 실패한 알림은 다시 큐에 넣고 지정된 횟수만큼 재시도한다.
  • 전송 템플릿을 사용하여 알림 생성 과정을 단순화하고 알림 내용의 일관성을 유지한다.
  • 모니터링과 추적 시스템을 주가하여 시스템 상태를 만들고 추후 시스템을 개선하기 쉽도록 하였다.


마무리

  • 안정성: 메세지 전송 실패율을 낮추기 위해 안정적인 재시도 메커니즘을 도입하였다.
  • 보안: 인증된 클라이언트만이 알림을 보낼 수 있도록 appKey, appSecret 등의 메커니즘을 이용하였다.
  • 이벤트 추적 및 모니터링: 알림이 만들어진 후 성공적으로 전송되기까지의 과정을 추적하고 시스템 상태를 모니터링하기 위해 알림 전송의 각 단계마다 이벤트를 추적하고 모니터링할 수 있는 시스템을 통합하였다.
  • 사용자 설정: 사용자가 알림 수신 설정을 조정할 수 있도록 하였다. 따라서 알림을 보내기 전 반드시 해당 설정을 확인하도록 시스템 설계를 변경하였다.
  • 전송률 제한: 사용자에게 알림을 보내는 빈도를 제한할 수 있도록 하였다.

댓글