본문 바로가기

IT서적/가상 면접 사례로 배우는 대규모 시스템 설계 기초

10장. 알림 시스템 설계

728x90

개요

  • 알림 시스템으로는 이메일, 모바일 푸시, 문자 서비스 세가지로 분류한다.

 

요구사항

1. 알림은 문자/이메일/푸시이다.

2. 연성 실시간 시스템으로 알림은 신속하지만 시스템의 높은 부하가 걸렸을 때 약간의 지연은 무방하다.

3. 단말은 IOS, ANDROID, 랩톱/데스크톱을 지원해야한다.

4. 사용자에게 보낼 알림은 클라이언트 애플리케이션 프로그램, 그리고 서버에서의 스케쥴링을 통해 만들 수 있다.

5. 사용자는 알림을 받지 않도록 설정할 수 있다.

6. 하루에 천만 건의 모바일 푸시 알림, 백만 건의 SMS 메시지, 5백만 건의 이메일을 보낼 수 있어야 한다.

 

개략적 설계

알림 유형 별 지원 방안

IOS 푸시 알림

 

컴포넌트

1) 알림 제공자 (provider) : 알림 요청을 만들어 알림 서비스(APNS)로 보내는 주체로, 알림 요청을 만들기 위한 JSON데이터 형식이 필요.

{
   "aps" : {
    "alert" : {
      "title" : "Message Request",
      "body" : "Hello",
      "action-loc-key" : "PLAY"
     },
  "badge" : 5
  }
}

 

2) APNS :  애플이 제공하는 원격 서비스로 푸시 알림을 IOS 디바이스로 보내는 역할을 한다.

3) IOS 단말 : 푸시 알림을 수신하는 사용자 단말

 

안드로이드 푸시 알림

  • IOS푸시와 비슷한 절차로 전송되며 APNS대신 FCM(Firebase Cloud Messaging)을 사용한다.

 

 

SMS 메시지

  • SMS 서비스는 보통 제 3사업자의 서비스를 이용한다.

 

이메일

  • 대부분의 회사는 고유 이메일 서버를 구축하지만 상용 이메일 서비스를 이용한다. 상용 이메일 서비스는 전송 성공률도 높고 데이터 분석 서비스도 제공한다.

 

연락처 정보 수집 절차

  • 알림을 보내기 위해서는 PUSH → 모바일 단말 토큰, 문자 → 전화번호, 이메일 → 이메일 주소 등의 주소가 필요하고 이에 대한 정보는 API호출 등을 이용해 DB에 저장한다.(PUSH의 경우 앱을 설치하면 자동으로 사용자 정보가 수집된다.)

사용자 정보가 담긴 DB 테이블 구조

 

알림 전송 및 수신 절차

초안 설계

 

1) 서비스1~서비스N :  서비스 각각은 MSA 또는 크론잡 또는 분산 시스템 컴포넌트일 수 있다. (예, 과금 서비스, 배송알림을 보내려는 쇼핑몰 웹사이트)

 

2) 알림 시스템 : 알림 전송/수싱 처리의 핵심으로 1개 서버만 사용하는 시스템이라고 가정할 때 이 시스템은 서비스 1~N에 알림 전송을 위한 API를 제공해야 하고, 제3자 서비스에 전달할 알림 페이로드를 만들 수 있어야 한다.

 

3) 제3자 서비스 : 이 서비스들은 사용자에게 알림을 실제로 전달하는 역할을 하고, 이 서비스와 통합을 진할할 때 확장성을 고려해야한다. 그리고 어떤 서비스는 다른 시장에 사용 불가할 수도 있으니 이 또한 고려해야 한다. (예를 들어 FCM은 중국에서는 이용 불가하다.)

 

4) IOS, 안드로이드 , SMS, 이메일 단말 : 사용자는 이 단말에서 알림을 수신한다.

 

위 그림의 설계의 문제점

  • SPOF(Single-Point-Of-Failure) : 알림 서비스에 서버가 하나 밖에 없는 것은 여기에 장애가 생기면 전체 서비스의 장애로 이어진다.
  • 규모 확장성 : 한 대 서비스로 푸시 알림에 관계된 모든 것을 처리하므로 DB나 캐시 등 중요 컴포넌트의 규모를 개별적으로 늘릴 방법이 없다.
  • 성능 병목 : 알림을 처리하고 보내는 것을 자원을 많이 필요로 하는 작업일 수 있다. 예시로 html페이지를 만들고 제3자 서비스의 응답을 기다리는 일은 시간이 많이 걸릴 가능성이 있는 작업으로 모든 것을 한 서버로 처리하면 사용자 트래픽이 많이 몰릴 때 시스템 과부하에 빠질 수 있다.

 

개선된 설계

1) DB와 캐시를 알림 시스템의 주 서버에서 분리

2) 알림 서버 증석하고 자동으로 수평적 규모 확장이 이뤄질 수 있도록 한다.

3) 메시지 큐를 이용해 시스템 컴포넌트 사이의 강한 결합을 끊는다.

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

 

위 그림의 컴포넌트 들의 알림 전송 흐름

1. API를 호출해서 알림 서버로 알림을 보낸다.

2. 알림 서버는 사용자 정보, 단말 토큰, 알림 설정 등의 메타 데이터를 캐시나 DB에서 가져온다.

3. 알림 서버는 전송할 알림에 맞는 이벤트를 만들어 해당 이벤트를 위한 큐에 넣는다.

4. 작업 서버는 메시지 큐에서 알림 이벤트를 꺼낸다.

5. 작업 서버는 알림을 제 3자 서비스로 보낸다.

6. 제3자 서비스는 사용자 단말로 알림을 보낸다.

 

상세 설계

안정성

  • 분산 환경의 알림 시스템은 안정성을 확보하기 위한 몇가지 사항을 반드시 고려한다.

데이터 손실 방지

  • 알림 전송 시스템에서 알림의 순서나 지연 정도는 무방하나 데이터 손실은 큰 장애이다.
  • 데이터 손실을 방지하기 위해서는 알림 데이터를 DB에 보관하고 재시도 메커니즘을 구현해야 한다.
  • 아래 그림은 알림 로그 DB를 유지하는 것이 한가지 방법이다.

 

 

알림 중복 전송 방지

  • 알림 중복 발송도 분산 시스템의 특성 상 가능하며 이 또한 장애 케이스이다.
  • 중복 발송을 방지하기 위해 중복을 탐지하는 메커니즘을 도입하고 오류를 신중하게 처리해야 한다.
  • 보내야 할 알림이 도착하면 이벤트ID를 검사하여 이전에 본 적이 있는 이벤트인지 확인하고 중복된 이벤트이면 버리고 아니면 알림을 발송한다.

 

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

알림 템플릿

  • 알림 템플릿은 인자나 스타일, 추적 링크를 조장하여 사전에 지정한 형식에 맞춰 알람을 만들어 내는 틀이다.
  • 알림 템플릿의 예
제목 : 안녕하세요 [name]님.
내용 : [name]님 께서 주문하신 상품 '[product_name]'이 발송 준비가 완료되었습니다.

 

 

알림 설정

  • 사용자가 알림을 on/off할 수 있는 기능으로, 이 기능은 테이블로 보관하고, 발송하기 전에 사용자의 알림 여부를 확인하고 발송한다.
컬럼 자료형 설명
user_id bigInt 사용자 아이디
channel varchar 알림이 전송될 채널, 푸시 알림, 이메일, SMS등
opt_in boolean 해당 채널로의 알림 수신 여부

 

전송률 제한

  • 사용자에게 너무 많은 알림을 보내 사용자가 알림을 수신거부 하지 않도록 하기 위해 한 사용자가 받을 수 있는 알림의 빈도를 제한한다.

 

재시도 방법

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

 

푸시 알림과 보안

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

 

큐 모니터링

  • 알림 시스템을 모니터링 할 때 중요한 메트릭 하나는 큐에 쌓인 알림의 캐수로 이 수가 너무 크면 작업 서버들이 이벤트를 빠르게 처리하고 있지 못한다는 의미이다. 이럴 경우 작업 서버를 증설하는게 좋다.

 

이벤트 추적

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

데이터 분석 서비스를 통해 추적하게 될 알림 시스템 이벤트의 사례

 

수정된 설계안

  • 아래 그림은 고려해야 할 사항들을 적용한 설계안이다.

많은 컴포넌트 들이 추가됨

 

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

 

정리

알림 전송 설계에 대해 고려한 항목

1. 안정성 (reliability) : 메시지 전송 실패율을 낮추기 위해 안전적인 재시도 메커니즘 도입

2. 보안 (security) : 인증된 클라이언트만이 알림을 보낼 수 있도록 appKey, appSecret 등의 메커니즘 이용

3. 이벤트 추적 및 모니터링 : 알림이 만들어진 후 성공적으로 전송되기 까지 과정을 추적하고, 시스템 상태를 모니터링하기 위해 알림 전송의 각 단계마다 이벤트를 추적하고 모니터링 할 수 있는 시스템 통합

4. 사용자 설정 : 사용자가 알림 수신 설정을 조정할 수 있게 함으로써 알림을 보내기 전 반디스 해당 설정을 확인 후 발송하도록 설계를 변경

5. 전송률 제한 : 사용자에게 알림을 보내는 빈도를 제한할 수 있도록 기능 추가