ch10 알림 시스템 설계

#시스템 디자인

알림 시스템 설계

  • 모바일 푸시 알림
  • SMS 메시지
  • 이메일

1단계 문제 이해 및 설계 범위 확정

  • 지원해야 하는 알림 종류
  • 실시간 시스템인지
  • 어떤 종류의 단말을 지원해야 하는지
  • 사용자에게 알림을 보낼 대상 (클라이언트인지, 서버측인지)
  • 알림을 받지 않도록 설정
  • 하루에 보낼 알림 개수

2단계 개략적 설계안 제시 및 동의 구하기

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

알림 유형별 지원 방안

ios 푸시 알림

image

  • 알림 제공자(provider) : 요청을 만들어 애플 푸시 알림 서비스(APNS : Apple Push Notification Service)로 보냄

    • 단말 토큰(device token) : 고유 식별자
    • 페이로드(payload) : 알림 내용 JSON 딕셔너리
  • APNS : 푸시 알림을 ios 장치로 보내는 역할

  • ios : 푸시 알림을 수신하는 사용자 단말

안드로이드 푸시 알림

FCM(Firebase Cloud Messaging)을 사용함

image

SMS 메시지

제3사업자 서비스 트월리오(Twilio) , 넥스모(Nexmo) 을 많이 이용 이용요금 발생

image

이메일

센드그리드(Sendgrid), 메일침프(Mailchimp)

image

연락처 정보 수집 절차

image

  • 알림을 보내기 위해서는
  • 모바일 단말 토큰, 전화번호, 이메일 주소 등의 정보가 필요
  • 앱 설치, 계정 등록때, 사용자의 정보를 수집하여 데이터베이스에 저장

image

  • 이메일 주소, 전화번호를 user 테이블에 저장

  • 단말 토큰을 device 테이블에 저장

  • 한 사용자가 여러 단말을 가질 수 있고, 알림은 모든 단말에 전송되도록

알림 전송 및 수신 절차

개략적 설계안(초안)

image

  • N개의 서비스(마이크로서비스, 크론잡, 분산 시스템 컴포넌트)

    • ex) 납기일을 알리는 과금 서비스, 배송알림을 보내는 쇼핑몰
  • 알림 시스템(notification system) : 알림 전송/ 수신 처리

    • 1개 서버만 사용하는 시스템이라고 할때, 서비스 N개의 알림 전송을 위한 API를 제공 하고 제3자 서비스에 전달할 페이로드를 만들 수 있어야 한다.
  • 제3자 서비스 : 사용자에게 알림을 실제로 전달하는 역할

  • ios, 안드로이드, SMS, 이메일 단말 : 알림을 수신하는 사용자 단말

3자 서비스와 통합할때 유의할것

확장성을 유의해야 한다. 서비스가 추가 제거가 쉬워야되고, 어떤 서비스는 다른 시장에서 사용하기 힘들 수 있다. ex) FCM은 중국에서 한정된 서비스만 사용가능하다 (제이푸시, 푸시와이)..

문제
  • SPOF : 알림 서비스에 서버가 하나 밖에 없다. 장애가 생기면 전체서비스에 장애로 이어진다.
  • 규모 확장성 : 한 대 서비스로 푸시 알림에 관계된 것을 처리, 데이터베이스나 캐시 등으로 중요 컴포넌트 규모를 개별적으로 늘릴 방법이 없다 -> ?
  • 성능 병목 : 알림 처리는 자원을 많이 필요할 수 있음
    • ex) HTML 페이지 만듬 제3자 서비스 응답 기다림, 사용자 트래픽이 몰릴 경우 과부하에 걸릴 수 있음
개략적 설계안(개선된 버전)
  • 데이터베이스, 캐시를 알림 시스템의 주 서버에서 분리
  • 알림 서버 증설, 자동으로 수평적 규모 확장되도록
  • 메시지 큐를 이용해 시스템 컴포넌트 사이 강한 결합 끊기

image

컴포넌트들 설명

  • N개의 서비스 : API를 통해 알림을 보냄

  • 알림 서버(notification server)

    • 알림 전송 API : 사내 서비스, 인증된 클라이언트만 이용 가능
    • 알림 검증(validation) : 이메일 주소, 전화번호에 대한 검증 수행
    • 데이터베이스 또는 캐시 질의 : 데이터 가져오기
    • 알림 전송 : 알림 데이터 메시지 큐에 넣고, 큐가 여러개이므로 알림을 병렬적으로 처리
  • 캐시(cache) : 사용자 정보, 단말 정보, 알림 템플릿 등을 캐시

  • 데이터베이스(DB) : 사용자, 알림, 설정 등 다양한 정보 저장

  • 메시지 큐 : 시스템 컴포넌트 간 의존성 제거하기 위해 사용

  • 다량의 알림 전송되어야 하는 경우를 대비한 버퍼 역할

  • 제3자 서비스 가운데 하나에 장애가 발생해도 다른 종류의 알림은 정상 동작

  • 작업 서버 : 알림 데이터를 제3자 서비스로 전달

? : 작업서버 장애나면 어떻게 하나? 오류 시 재시도를 통해서 처리

알림 전송 흐름

  1. API 호출 후 알림 서버로 전송
  2. 메타데이터를 캐시, 데이터베이스에서 가져옴
  3. 알림 서버는 이벤트를 생성해서 큐에 넣는다.
  4. 작업 서버는 큐에서 알림 이벤트를 꺼낸다.
  5. 작업 서버는 알림을 제3자 서비스로 전송한다.
  6. 제3자 서비스는 사용자 단말로 알림을 전송한다.

3단계 상세 설계

안정성

데이터 손실 방지

어떤 상황에서도 알림이 소실되면 안된다

지연되거나 순서가 틀려도 괜찮음

알림 데이터를 데이터베이스에 보관, 재시도 메커니즘을 구현

image

알림 로그 데이터베이스를 유지하는 것

알림 중복 전송 방지

완전히 막는것은 불가능

빈도를 줄이는 것을 목표

중복을 탐지하는 메커니즘을 도입하여, 오류를 신중하게 처리해야 한다.

중복 방지 사례

  • 보내야할 알림이 도착하면 이벤트 ID를 검사하여 이전에 본 적이 있는 이벤트인지 살핌
  • 중복된 이벤트라면 버리고, 그렇지 않으면 전송

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

  • 알림 템플릿
  • 알림 설정
  • 이벤트 추적
  • 시스템 모니터링
  • 처리율 제한
알림 템플릿

알림 메시지 형식은 대부분 비슷하기에, 템플릿을 구현

인자, 스타일, 추적 링크를 조정하면 지정된 형식에 맞춰서 알람을 만들어 냄

본문 형식: 여러분이 꿈꿔온 그 상품을 우리가 준비했습니다. [item_name]이 다시 입고 되었습니다! [date]까지만 주문 가능합니다!

타이틀(CTA: Call to Action): 지금 [item_name]을 주문 또는 예약하세요!

장점

형식 일관성 유지 오류 가능성 줄어듬 알림 작성 시간 절약

알림 설정

사용자가 너무 많은 알림을 받아서 피곤함을 느낌 사용자가 알림 설정을 상세히 조정할 수 있도록 알림 설정 테이블에 보관

nametype
user_idbigInt
channelvarchar
opt_inboolean

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

전송률 제한

사용자에게 너무 많은 알림을 보내지 않도록 하는 방법 중 하나로, 한 사용자가 받을 수 있는 알림 빈도를 제한하는 것이다.

너무 많이 보내면 사용자가 알림 기능을 꺼버릴 수 있기 때문이다.

재시도 방법

제3자 서비스가 알림 전송에 실패하면, 재시도 전용 큐에 넣기 같은 문제가 반복되서 발생하면 개발자에게 alert하도록

푸시 알림과 보안

ios, 안드로이드 앱의 경우, 알림 전송 API는 appKey와 appSecret을 사용하여 보안 유지

인증된, 승인된 클라이언트만 해당 API를 사용하여 알림 전송

큐 모니터링

큐에 쌓인 알림의 개수

수가 너무 크면 작업 서버들이 이벤트를 빠르게 처리하고 있지 못하다는 뜻

작업 서버를 증설하는게 바람직 할것이다.

image

이벤트 추적

알림 확인율 클릭율 실제 앱 사용

사용자를 이해하는게 중요

데이터 분석 서비스는 보통 이벤트 추적 기능을 제공

image

  • 데이터 분석 서비스를 통해 추적할 알림 시스템 이벤트
수정된 설계안

image

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

4단계 마무리

시스템 컴포넌트 사이 결합도를 낮추기 위해 메시지 큐 적극적으로 사용

이번장에서 집중한 것들

  • 안정성(reliability) : 메시지 전송 실패율 낮추기 위해 , 재시도 메커니즘
  • 보안(security) : 인증된 클라이언트만이 알림 보낼 수 있도록 appKey, appSecret 등의 메커니즘 이용
  • 이벤트 추적 및 모니터링 : 알림 생성 후 전송 성공할때까지, 모니터링할 수 있도록
  • 사용자 설정 : 사용자가 알림 수신 설정을 조정할 수 있도록, 알림 보내기전 해당 설정 확인하도록
  • 전송률 제한 : 사용자에게 알림 보내는 빈도를 제한할 수 있도록

다음 챕터