읽은 책/[책] 가상 면접 사례로 배우는 대규모 시스템 설계 기초 1권

10장. 알림 시스템 설계

코드몬스터 2024. 7. 15. 00:14
728x90

 

알림 시스템은 최신 뉴스, 제품 업데이트, 이벤트 등 고객에게 중요할 만한 정보를 비동기적으로 제공한다.

알림 시스템을 설계해보자.

 

문제 이해 및 설계

  • 푸시 알림, SMS 메세지 그리고 이메일
  • 가능한 빨리 전달되어야 하지만, 시스템에 부하가 있을 때는 약간의 지연이 무방
  • iOS 단말, 안드로이드 단말, 랩톱/데스크톱 지원
  • 클라이언트 애플리케이션, 서버측 스케쥴링
  • 알림을 받지 않도록 설정하면 더 이상 알림을 받지 않는다.

 

개략적 설계

iOS 푸시 알림, 안드로이드 푸시 알림, SMS 메세지 그리고 이메일을 지원하는 알림 시스템의 개략적 설계를 살펴보자.

  • 알림 유형별 지원 방안
  • 연락처 정보 수집 절차
  • 알림 전송 및 수신 절차

알림 유형별 지원 방안

  •  iOS 푸시 알림
    • 알림 제공자: 알림 요청을 만드는 자.
      - 단말 토큰(device toke): 알림 요청을 보내는데 필요한 고유 식별자
      - 페이로드(payload): 알림 내용을 담은 JSON 딕셔너리이다.
    • APNS: 애플이 제공하는 원격 서비스, 푸시 알림을 iOS 장치로 보내는 역할
    • iOS 단말: 푸시 알림을 수신하는 사용자 단말

  • 안드로이드 푸시 알림
    • 안드로이드 푸시 알림도 비슷한 절차로 진행
    • APNS 대신 FCM을 사용하여 진행
  • SMS 메세지
    • 트윌리오, 넥스모 같은 제 3 사업자의 서비스를 많이 사용
    • 상용 서비스로 이용 요금을 내야한다.
  • 이메일
    • 대부분의 회사는 고유 이메일 서버를 구축한다.
    • 상용 이메일버시스를 이용하기도 한다.

 

연락처 수집 절차

사용자가 앱을 설치하거나 처음으로 계정을 등록하면 API 서버는 해당 사용자의 정보를 수집하여 데이터베이스에 저장

 

 

알림 전송 및 수신 절차

개략적 설계안(초안)

  • 1부터 N까지의 서비스
    • 해당 서비스는 마이크로서비스, 크론잡, 분산 시스템 컴포넌드일 수도 있다.
    • 알림을 보내려고 하는 주체
  • 알림시스템
    • 알림 전송/수신 처리의 핵심
    • 알림 전송을 위한 API를 제공해야하고, 제 3자 서비스에 전달할 알림 페이로드를 만들어야 한다.
  • 제 3자 서비스
    • 사용자에게 알림을 실제로 전달하는 역할
    • 확장성을 고려해서 설계해아한다. 중국에서는 FCM을 사용할 수 없다.
  • iOS, Android, SMS 단말: 사용자는 자기 단말에서 알림을 수신

 

몇 가지 문제점이 존재하는 구조

  •  SPOF: 알림 서비스에 서버가 하나 밖에 없다는 것은, 서버에 장애가 생기면 전체 서비스의 장애로 이어진다.
  • 규모 확장성: 한 대 서비스로 푸시 알림에 관계된 모든 것을 처리하므로, 데이터베이스나 캐시 등 중요 컴포넌트의 규모를 늘릴 방법이 없다.
  • 성능 병목: 모든 것을 한 서버로 처리하면 사용자 트래픽이 많이 몰리는 시간에는 시스템이 과부하 상태에 빠질 수 있다/

 

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

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

 

추가된 부분

  • 캐시: 사용자 정보, 단말 정보, 알림 템플릿 등을 캐시
  • 데이터베이스: 사용자, 알림, 설정 등 다양한 정보를 저장
  • 메세지 큐: 시스템 컴포넌트 간 의존성을 제거하기 위해 사용 다량의 알림이 전송되어야 하는 경우를 대비한 버퍼 역할
  • 작업 서버: 메세지 큐에 전송할 알림을 꺼내서 제 3자 서비스로 전달하는 역할을 담당

 

 

상세설계

안전성

분산 환경에서 안정성을 확보하기 위한 고려사항

 

데이터 손실 방지

  • 어떤 상황에서도 알림이 소실되면 안 된다.
  • 해당 요구사항을 만족하려면 알림 데이터를 데이터베이스에 보관하고 재시도 메커니즘을 구현해야 한다.

알림 중복 전송 방지

  • 같은 알림이 여러 번 반복되는 것을 완전히 막는 것은 불가능하다.
  • 분산 시스템 특성상 가끔은 같은 알림이 중복되어 전송된다.
  • 보내야하는 알림이 도착하면 이벤트 ID를 검사하여 이전에 본 적이 있는 이벤트인지 살펴본다. 중복된 이벤트라면 버리고, 그렇지 않으면 알림을 발송

 

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

알림템플릿

  • 알림 메세지 대부분 형식이 비슷하기 때문에 사전에 지정한 형시게 맞춰 알람을 만들어 내는 틀.
  • 예시) [item_name]이 다시 입고 되었습니다! [date]까지만 주문 가능합니다.

알림 설정

  • 웹사이트와 앱에서 사용자가 알림 설정을 상세히 조정할 수 있도록 설정이 필요
  • 해당 정보는 알림 설정 테이블에 보관

user_id    bigInt

channel   varchar     # 알림이 전송될 채널. 푸시 알림, 이메일, SMS 등

opt_in      boolean    # 해당 채널로 알림을 받을 것인지 여부

 

전송률 제한

  • 한 사용자가 받을 수 있는 알림의 빈도를 제한하는 것.
  • 너무 많이 보내면 알림을 아예 꺼버릴 수 있다.

재시도 방법

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

푸시 알림과 보안

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

큐 모니터링

  • 알림 시스템 모니터링에서 큐에 쌓인 알림의 개수는 중요한 메트릭이다.
  • 해당 큐에 알림 개수가 많으면 서버가 이벤트 처리를 제대로 하지 못하고 있다는 것으로 서버 확장이 필요하다.

이벤트 추적

  • 알림 확인율, 클릭율, 실제 앱 사용으로 이어지는 비율 같은 메트릭은 사용자를 이해하는데 중요하다.
  • 데이터 분석 서비스는 이러한 이벤트 추적 기능을 제공한다.
  • 보통 알림 시스템을 만들면 데이터 분석 서비스와도 통합한다.

 

수정된 설계안

지금까지의 내용을 반영한 수정 설계안

  • 알림 서버에 인증과 전송률 제한 기능을 추가
  • 전송 실패에 대응하기 위한 재시도 기능 추가
  • 전송 템플릿을 사용하여 생성과정을 단순화
  • 모니터링과 추적 시스템을 추가하여 시스템을 개선하기 쉽도록 함.