티스토리 뷰

책/misc

알림 시스템 설계

kingsubin 2022. 7. 9. 16:11

알림 시스템 설계

알림 시스템은 단순히 모바일 푸시 알림(mobile push notification)에 한정되지 않고 모바일 푸시 알림, SMS 메시지, 이메일 세 가지로 분류할 수 있다.

 

1. 요구사항 분석

어떤 종류의 알림 지원할 것인지?

- 푸시 알림, SMS 메시지, 이메일

 

실시간 시스템(real-time) 시스템인가?

- 연성 실시간(soft real-time)

 

어떤 종류의 단말 지원할 것인지?

- iOS, Android, desktop

 

사용자에게 보낼 알림은 누가 만드는가?

- 클라이언트 애플리케이션 프로그램 또는 서버 측에서의 스케쥴링

 

알림을 받지 않도록(opt-out) 설정 가능한가?

- 가능해야 함.

 

하루에 몇 건의 알림이 필요한가?

- 1,000만 건 모바일 푸시, 100만 건 SMS, 500만 건 이메일

 

2. 개략적 설계안

알림 유형별 지원 방안

iOS push notification

iOS에서 push notification을 보내기 위해서는 세 가지 컴포넌트가 필요하다.

 

- provider: notification request를 만들어 APNS(Apple Push Notification Service)로 보내는 주체다.

  - push notification을 만들기 위해 필요한 데이터:

    - device token: 알림 요청을 보내는데 필요한 고유 식별자

    - payload: 알림 내용을 담은 JSON

- APNS: 애플이 제공하는 원격 서비스, push notification을 iOS 장치로 보내는 역할을 한다.

- iOS 단말: push notification을 수신하는 사용자 단말

// payload ex
{
  "aps": {
    "alert": {
      "title": "Game Request",
      "body": "Bob wants to play chess",
      "action-loc-key": "PLAY"
    },
    "badge": 5
  }
}

 

안드로이드 푸시 알림

iOS push notification와 비슷한 절차로 전송되지만 APNS 대신 FCM(Firebase Cloud Messaging)을 사용한다는 점이 다르다.

 

SMS 메시지

보통 Twilio, Nexmo와 같은 제3 사업자의 서비스를 많이 이용한다.

 

 

이메일

고유 이메일 서버를 구축할 수도 있지만, 많은 회사가 상용 이메일 서비스를 이용한다.

그중에 Sendgrid, Mailchimp가 유명하고 전송 성공률도 높고, 데이터 분석 서비스도 제공한다고 한다.

 

연락처 정보 수집 절차

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

사용자가 앱을 설치하거나 처음 계정 등록 시 API 서버는 해당 사용자의 정보를 수집하여 DB에 저장한다.

 

DB 테이블 구조의 예시:

 

개략적 설계 - 1

각 컴포넌트에 대한 설명:

  • 서비스: microservice일 수도 있고, cronjob일 수도 있고, 분산 시스템 컴포넌트일 수도 있다. 납기일을 알리는 과금 서비스, 배송 알림을 보내려는 쇼핑몰이 예시다.
  • 알림 시스템: 1개 서버만 사용하는 시스템이라고 가정하면, 이 시스템은 서비스 1~N에 알림 전송을 위한 API를 제공해야 하고, 제3자 서비스에 전달할 알림 payload를 만들어 낼 수 있어야 한다.
  • 제3자 서비스: 사용자에게 알림을 실제로 전달하는 역할, 통합을 진행할 때 유의할 점은 확장성이다. 또 고려할 점은 어떤 서비스는 다른 시장에서 사용할 수 없을 수도 있다. 예를 들어 FCM은 중국에서 사용할 수 없어 중국 시장에서는 Jpush, PushY와 같은 서비스를 사용해야만 한다.
  • 단말: 사용자는 본인 단말에서 알림을 수신한다.

 

해당 설계의 문제점:

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

 

개략적 설계 - 2

위 개략적 설계 - 1의 문제점을 보았으니 아래 방향으로 개선해보자.

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

알림 서버:

  • 알림 전송 API: 스팸 방지를 위해 보통 사내 서비스 또는 인증된 클라이언트만 이용 가능
  • 알림 검증: 이메일 주소, 전화번호 등에 대한 기본적 검증
  • DB 또는 캐시 질의: 알림에 포함시킬 데이터 가져오기
  • 알림 전송: 알림 데이터를 MQ에 넣는다. 해당 설계안은 하나 이상의 MQ를 사용하므로 알림을 병렬적으로 처리할 수 있다.

캐시:

  • 사용자 정보, 단말 정보, 알림 템플릿 등을 캐시 한다.

DB:

  • 사용자 알림, 설정 등 다양한 정보 저장

MQ:

  • 시스템 컴포넌트 간 의존성 제거하기 위해 사용
  • 다량의 알림을 대비한 버퍼 역할
  • 해당 설계안은 알림 종류별 MQ를 사용하여 제3자 서비스 가운데 하나에 장애가 발생해도 다른 종류의 알림은 정상 작동한다.

작업 서버:

  • MQ에서 전송할 알림을 꺼내서 제3자 서비스로 전달하는 역할을 담당

 

전체 흐름:

  1. API 호출하여 알림 서버로 알림을 보냄.
  2. 알림 서버는 사용자 정보, 단말 토큰, 알림 설정 같은 메타데이터를 캐시나 DB에서 가져옴.
  3. 알림 서버는 전송할 알림에 맞는 이벤트를 만들어 해당 MQ에 넣는다.
  4. 작업 서버는 MQ에서 이벤트를 꺼내서 제3자 서비스로 보낸다.
  5. 제3자 서비스는 사용자 단말로 알림을 전송한다.

3. 상세 설계

안전성

분산 환경에서 운영될 알릴 시스템을 설계할 때는 안전성 확보를 위한 몇 가지 사항을 반드시 고려해야 한다.

 

데이터 손실 방지

알림 전송 시스템은 지연되거나 순서가 틀릴 순 있지만 어떤 상황에서도 알림이 소실되면 안 된다.

이 요구사항을 만족하려면 알림 시스템은 알림 데이터를 DB에 보관하고 재시도 메커니즘을 구현해야 한다.

위 그림과 같이 알림 로그 DB를 유지하는 것이 한 가지 방법이다.

 

알림 중복 전송 방지

같은 알림이 여러 번 반복되는 것을 완전히 막는 것은 가능하지 않다. 대부분의 경우 한 번만 전송되겠지만, 분산 시스템 특성상 가끔은 알림이 중복되어 전송되기도 할 것이다.

그 빈도를 줄이려면 중복을 탐지하는 메커니즘을 도입하고, 오류를 신중하게 처리해야 한다.

  • 보내야 할 알림이 도착 → 이벤트 ID 검사하여 이전에 본 적 있는지 확인

 

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

알림 템플릿

대형 알림 시스템은 하루에도 수백만 건 이상의 알림을 처리하는데 대부분의 알림 메시지는 형식이 비슷하다.

이런 유사성을 고려하여 미리 템플릿을 만들어 두면 형식의 일관성 유지, 오류 가능성 및 알림 작성 시간 감소가 가능하다.

template:

본문: 안녕하세요. ... [item_name]이 다시 입고되었습니다. [date]까지 주문 가능합니다.
타이틀(CTA: Call to Action): [item_name]을 주문하세요.

 

알림 설정

사용자는 너무 많은 알림을 받기 싫을 수 있으니 사용자가 알림 설정을 상세히 조정할 수 있도록 해야 한다.

이 정보는 알림 설정 테이블에 보관된다. 아래 그림은 알림 설정 테이블의 예시이다.

 

전송률 제한

알림을 너무 많이 보내면 사용자가 아예 알림을 꺼 버릴 수도 있으니 한 사용자가 받을 수 있는 알림 빈도를 제한하여 사용자에게 너무 많은 알림을 보내지 않도록 한다.

 

재시도 방법

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

 

푸시 알림과 보안

iOS와 Android 앱의 경우 알림 전송 API는 appKey, appSecret을 사용하여 보안을 유지한다. 따라서 인증되거나 승인된 클라이언트만 해당 API를 사용하여 알림을 보낼 수 있다.

 

큐 모니터링

알림 시스템 모니터링 시 중요한 메트릭은 큐에 쌓인 알람의 개수이다. 이 수가 너무 크면 작업 서버가 이벤트를 처리하지 못하고 있다는 뜻이니 작업 서버를 증설해야 한다.

 

이벤트 추적

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

 

수정된 설계안

개략적 설계 - 2 에서 변경된 내용:

  • 알림 서버에 인증과 전송률 제한 기능 추가
  • 전송 실패를 대비한 재시도 기능 추가
  • 알림 템플릿 사용, 알림 로그 저장
  • 모니터링과 추적 시스템 추가

참고: 가상 면접 사례로 배우는 대규모 시스템 설계 기초

' > misc' 카테고리의 다른 글

1장. 타입스크립트 알아보기  (0) 2022.07.17
분산 시스템을 위한 유일 ID 생성기 설계  (0) 2022.07.09
안정 해시 설계  (2) 2022.06.21
처리율 제한 장치의 설계  (3) 2022.06.19
3장. HTTP 메시지  (0) 2022.05.02