알림 시스템 설계

코딩하는스님·2022년 1월 26일
2
post-thumbnail
  • 알림 시스템은 비동기적으로 사용자에게 정보를 제공할 때 유용하게 쓰인다.
    • 모바일 푸시
    • SMS
    • 이메일

문제 이해 및 설계 범위 확정

  • 하루에 수백만 건의 알림을 보내는 확장성 있는 시스템을 구축하는 것은 쉽지 않기 때문에 구현에 대한 깊은 이해가 필요하다.

질문

  • 어떤 종류의 알림을 지원해야 하나? 푸시, SMS, 이메일
  • 실시간이어야 되나요? soft-real-time, 가능한 빨리 하지만 부하가 있을 땐 늦어도 된다.
  • 어떤 종류의 단말을 지원해야 되나요? iOS, AOS, 데스크탑, 랩탑
  • 알림은 누가 만드나요? 클라이언트 프로그램, 서버 스케줄
  • 알림을 받지 않을 수 있게 설정할 수 있나요?
  • 하루에 몇 건까지 보내야 되나요? 천만 건의 푸시, 백만 건의 SMS, 5백만 건의 이메일

개략적 규모 추정

  • QPS : 10,000,000 / 24 / 60 / 60초 = 115/초
  • 하지만 알림의 특성 상 특정 시간에 몰리는 경우가 많다.

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

알림 유형별 지원 방안

iOS 푸시 알림

  • 알림 provider
    • notification request를 만들어 APNS에 보내는 주체
    • device token : 알림 요청을 보내는 데 필요한 고유 식별자
    • payload : 알림 내용을 담은 객체
{
	"aps" : {
    	"alert" : {
        	"title" : "game request",
          	"body" : "hello world",
        }
      	"badge" : 5
    }
}
    
  • APNS (Apple Push Notification Service)
    • 애플이 제공하는 원격 서비스, 푸시 알림을 단말로 전달한다.
  • iOS device
    • 푸시 알림을 수신하는 단말

AOS 푸시 알림

  • APN 대신 FCM(Firebase Cloud Messaging)을 사용한다.

SMS

  • KT surem 등의 상용 서비스를 이용한다.

이메일

  • 사용 이메일 서비스를 이용

연락처 정보 수집 절차

  • 앱을 설치하여 계정을 등록할 때, 이메일이나 전화번호, 기기의 단말 고유 번호(단말 토큰) 등을 수집하여 DB에 저장한다.

알림 전송 및 수신 절차

무지성 설계

  • N개의 서비스
    • 마이크로서비스
    • 크론잡
    • 분산 시스템 컴포넌트
    • 과금서비스 / 배송알림 등
  • 알림 시스템
    • N개 서비스에 알림 전송을 위한 API 제공
      -3자 서비스에 전달할 payload도 만들어 내야한다.
  • 3자 서비스
    • 사용자에게 알림을 전달하는 역할
    • 확장성, 서비스 통합이나 제거가 쉬워야 한다.
    • 중국같은 곳에서는 FCM을 쓸 수 없다.
  • 단말
    • 자기 단말에서 알림을 수신해야 된다.
  • SPOF
    • 알림 서비스가 하나 밖에 없으면 그 서버에 장애가 생기면 전체 서비스에 장애가 생긴다.
  • 규모 확장성
    • 한 대 서비스로 푸시 알림에 관계된 모든것을 처리하므로 DB나 캐시 등 컴포넌트의 규모를 개별적으로 늘릴 수 없다.
  • 성능 병목
    • 알림을 처리하고 보내는 것이 자원을 많이 사용하는 작업일 경우 트래픽이 모려 과부하 상태에 빠질 수 있다.

지성 설계

  • DB와 캐시를 알림 시스템 서버에서 분리한다.

  • 알림 서버를 증설하고 scale out이 이루어질 수 있게 한다.

  • MQ를 사용하여 coupling을 줄인다. (pub-sub pattern)

  • 알림 시스템

    • 알림 전송 API : 인증된 클라이언트만 알림을 전송한다.
    • 알림 검증 : target에 대한 검증을 수행한다.
    • DB/Cache query : 알림 데이터에 포함될 데이터를 가져온다.
    • 알림 전송 : MQ에 알림 데이터를 넣는다.
  • cache : 알림에 보낼 데이터를 캐싱한다.

  • DB : 알림에 대한 정보를 저장한다.

  • MQ : 시스템 간 의존성을 제거하고 버퍼 역할을 한다.

  • worker server : MQ에서 알림을 꺼내어 발송한다.

  • 3rd party service

  • 단말

발송 flow

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

상세 설계

안정성

데이터 손실 방지

  • 지연이나 순서의 변경은 괜찮지만 소실은 허용되지 않는다.
  • 재시도 메커니즘을 구현해야 된다.
  • 알림 로그 DB를 유지하여 발송 여부를 저장한다.

알림 중복 전송 방지

  • 분산 시스템의 특성상 완벽하게 중복을 제거할 수는 없다.
  • 보내야할 알림이 도착하면 그 이벤트를 검사하여 중복 여부를 체크한다. 중복이 아니라면 발송한다.

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

알림 템플릿

  • 템플릿을 만들어 서버의 부하를 줄인다.

알림 설정

  • 사용자는 알림으로부터 피곤함을 느낄 수 있다.
  • 따라서 사용자가 알림을 받을지 설정할 수 있도록 제공해야된다.

전송률 제한

  • 알림으로부터 피곤함을 줄이기 위해서 사용자별로 빈도를 제한하는 방법이 있다.

재시도 방법

  • 발송이 실패하면 재시도 전용 MQ에 넣고 계속 실패한다면 개발자에게 통지한다.

푸시알림과 보안

  • 인증된 클라이언트만 푸시를 보낼수 있도록 한다.

큐 모니터링

  • 큐에 쌓이는 알림의 개수를 모니터링함으로서 작업 서버의 scaling을 결정한다.

이벤트 추적

  • 알림을 보낸 후에 알림에 대한 metric을 집계하는 것도 중요하다.

수정된 설계안

마무리

참조

알렉스 쉬, 가상 면접 사례로 배우는 대규모 시스템 설계 기초, 인사이트, 2021, 165p-181p

profile
👨🏻‍💻👨🏽‍🦲

0개의 댓글