알림 시스템 설계

DongHwan·2022년 8월 13일
0

Design

목록 보기
9/11

"가상 면접 사례로 배우는 대규모 시스템 설계 기초"를 읽고 정리한 글입니다 :)

사용자에게 알림을 보내는 알림 시스템(Notification System)을 설계해보자. 알림 시스템을 갖춘 서비스들은 최신 뉴스, 제품 업데이트, 이벤트 등 고객에게 중요할 만한 정보를 비동기적으로 제공한다. 이 알림 시스템은 단순히 모바일 푸시 알림에 한정되지 않는다. 일반적으로 알림 시스템은 모바일 푸시 알림, SMS 메시지, 이메일 세가지로 분류할 수 있다.

고려할 요구사항

알림 시스템을 설계할 때 고려할 점들은 다음과 같다.

  • 어떤 종류의 알림을 지원하는지
  • 실시간(Real-Time) 시스템이어야 하는지
    • 더 나아가 Hard Real Time 혹은 Soft Real Time
  • 지원해야하는 단말
    • ios, 안드로이드, 데스크탑 등
  • 알림을 만드는 주체
    • 클라이언트 프로그램이 직접 만들 수도 있지만, 서버의 스케쥴링을 통해 만들어질 수도 있음
  • 사용자가 알림을 받지 않도록 설정할 수 있는가? (Opt-Out)
  • 보내는 알림의 트래픽

알림 유형별 메커니즘

설계하기에 앞서 우선 지원하는 알림 유형들의 동작 흐름을 알고있어야 한다.

ios

출처: http://www.googleplus.party/2017/01/18/PushNotification-in-C-Objective-c-C/

ios의 푸시 알림은 APNS(Apple Push Notification Service)를 통해 제공할 수 있다.
알림 제공자(Provider)는 알림 요청(Notification Request)를 만들어 APNS로 보내는 주체이다. 이때 알림 객체를 만들기 위해서는, 알림을 보낼 객체를 나타내는 고유 식별자인 단말 토큰(Device Token)과 알림 내용을 담은 JSON 딕셔너리인 페이로드가 필요하다.

안드로이드

안드로이드도 ios와 비슷한 절차로 전송된다. ios와의 차이는 APNS 대신 FCM(Firebase Cloud Messaging)을 쓴다는 점이다.

SMS 메시지

출처: https://www.wenyanet.com/opensource/ko/603fd1fa7df6d662205ae1d3.html

SMS 메시지를 보낼 때는 Twilio, Nexmo와 같은 Third-Party Service를 많이 이용한다.

이메일

대부분의 회사는 고유 이메일 서버를 구축할 역량을 갖추고 있다. 그럼에도 많은 회사가 사용 이메일 서비스를 이용한다. 이러한 서비스들은 전송 성공률이 높고, 데이터 분석 서비스도 제공하기 때문이다.

정보 수집

알림을 보내기 위해서는 사용자의 정보를 수집할 필요가 있다. 지원하는 알림의 종류에 따라 휴대전화 번호, 이메일, 디바이스 토큰 등을 적절히 수집하여 저장해야 한다.

가장 단순한 설계안

가장 기초적인 설계는 알림 시스템으로 한개의 서버만을 사용하는 것이다. 이 시스템은 여러 서비스(크론잡, 마이크로서비스 등)가 알림 전송을 할 수 있는 API를 제공해야 하고, 제 3자 서비스에 전달할 알림 페이로드를 만들어낼 수 있어야 한다.

이때 제 3자 서비스와의 통합을 진행할 때 유의할 점은 확장성(Extensibility)이다. 쉽게 새로운 서비스를 통합하거나 기존 서비스를 제거할 수 있어야 한다는 점이다. 또 하나 고려해야할 것은, 어떤 서비스는 다른 시장에서 사용할 수 없을 수 있다. 가령 FCM은 중국에서 사용할 수 없고, 중국 시장에서는 제이푸시와 같은 서비스를 이용해야 한다.

한개의 서버를 사용하는 기초적인 설계에는 몇가지 문제가 있다.

  • SPOF(Single-Point-Of-Failure) : 알림 서비스에 서버가 하나밖에 없기에 SPOF가 된다.
  • 규모 확장성 : 하나의 서비스로 알림과 관계된 모든 것을 처리하므로, DB나 캐시 등 중요 컴포넌트를 개별적으로 늘릴 방법이 없다.
  • 성능 병목 : 알림을 처리하고 보내는 것은 자원을 많이 필요로 하는 작업이기에, 시스템이 과부화될 수 있다.

개선된 설계안

위에서 언급한 문제를 해결하기 위해 몇가지 개선책을 적용해보자.

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

이 개선책을 적용한 설계안에서는 알림 서버와 작업 서버를 분리한다. 그리고 알림 서버와 작업 서버를 메시지 큐를 데이터를 전송할 수 있도록 한다.

알림 서버는 다음과 같은 기능들을 제공할 것이다.

  • 알림 전송 API : 서비스들이 호출할 수 있는 API
  • 알림 검증(Validation) : 이메일 주소, 전화번호 등에 대한 기본적인 검증
  • DB 또는 캐시 질의 : 알림에 포함시킬 데이터를 가져온다.
  • 알림 전송 : 알림 데이터를 메시지 큐에 넣는다.

메시지 큐는 시스템 컴포넌트 간의 의존성을 제거하기 위해 사용한다. 해당 설계에서는 알림 서버가 메시지 큐에만 데이터를 넣으면 되고, 작업 서버가 어떻게 되든 알 필요가 없으므로 의존성이 제거된다. 메시지 큐는 의존성 제거 말고도 트래픽이 몰릴 경우를 대비한 버퍼 역할도 한다.
또한, 메시지 큐를 알림의 종류 별로 따로 사용할 수 있는데, 이 경우 하나의 제 3자 서비스에 장애가 발생하더라도 다른 종류의 알림은 정상동작한다.

작업 서버는 메시지 큐로부터 전송할 알림 데이터를 꺼내서 제 3자 서비스로 전달하는 역할을 담당한다.

상세 설계

알림 서비스를 조금 더 상세하게 설계하자면 고려할 점은 다음과 같다.

  • 안정성(Reliability)
  • 알림 템플릿
  • 알림 설정
  • 전송률 제한
  • 재시도 메커니즘
  • 보안
  • 큐 모니터링
  • 이벤트 추적

안정성

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

우선 알림 시스템의 가장 중요한 요구사항 중 하나는 어떤 상황에서도 알림이 소실되면 안되는 것이다. 알림이 지연되거나 순서가 틀리는 일은 있을 수 있어도, 사라지면 곤란하다. 이 요구사항을 만족하려면, 알림 시스템은 알림 데이터를 DB에 보관하고 재시도 메커니즘을 구현해야 한다.

다음으로는 알림이 중복으로 전송되는 것을 막아야 한다. 분산 시스템의 특성상 이것을 완벽히 막는 것은 불가능하다. 하지만 최소한 그 빈도를 줄일려면 중복을 탐지하는 메커니즘을 도입하고, 오류를 처리할 필요가 있다. 예를 들어 보낼 알림의 이벤트 ID를 검사하여 이전에 처리한 메일인지 확인하는 방법이 있을 수 있다.

알림 템플릿

대형 알림 시스템은 하루에도 수백만 건 이상의 알림을 처리한다. 그런데 이 알림 메시지의 대부분은 그 형식이 빗스하다. 그렇기에 알림 템플릿은 이런 유사성을 고려하여, 파라미터나 스타일를 조정하여 지정된 형식에 맞춰 알림을 만들 수 있게 한다.

알림 설정

사용자가 특정 알림을 받지않도록 설정할 수 있어야 한다. 이러한 설정 정보들을 저장하여, 사용자가 특정 알림을 받지않도록 설정했다면 보내면 안된다.

전송률 제한

특정 사용자에게 너무 많은 알림을 보내지 않도록 알림의 빈도를 제한할 수 있어야 한다. 또한, 만약 알림 시스템을 제 3자 서비스가 호출할 수 있다면, 호출자에 대한 전송률 제한도 필요할 것이다.

재시도 메커니즘

제 3자 서비스 혹은 알림 시스템이 알림 전송에 실패한다면, 해당 알림을 다시 큐에 넣고 재시작할 수 있어야 한다. 또한, 같은 알림의 전송이 여러번 실패하거나 실패하는 알림의 빈도가 많다면, 개발자에게 통지할 수 있어야 한다.

보안

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

큐 모니터링

알림 시스템을 모니터링 할 때 중요한 메트릭(Metric) 중 하나는 큐에 쌓인 알림의 개수이다. 이 수가 너무 크면 작업 서버들이 이벤트를 빠르게 처리하지 못하고 있다는 뜻이므로, 작업 서버를 증설하는 등의 적절한 조치를 취해야한다.

이벤트 추적

알림 확인률, 클릭율과 같은 분석 결과들은 사용자를 이해하는데 중요하다. 데이터 분석 서비스는 보통 이벤트 추적 기능도 제공하므로, 보통 알림 시스템을 만들면 데이터 분석 서비스와도 통합해야한다.

profile
날 어떻게 한줄로 소개해~

0개의 댓글