알림 시스템 설계

알림 시스템은 많은 애플리케이션에서 사용됩니다.

제품 업데이트, 이벤트, 피드 등 다양한 분야에서 정보를 제공하기 위해 사용됩니다.

 

비즈니스 로직을 처리하는 여러 서버들이 있다고 가정하고

알림 시스템을 설계해서 다양한 종류의 단말기에 알림을 전송하는 시스템을 설계해보겠습니다.

 

문제 이해 및 설계 범위

 

우선 문제를 정의해보겠습니다.

 

푸시 알림과 SMS, 이메일의 알림을 지원합니다.

soft real-time 시스템, 가능한 빠르게 전달되어야합니다만, 부하에 따라 약간의 지연은 무방합니다.

IOS와 안드로이드 단말기와 데스크톱을 지원합니다.

사용자가 알림을 받지 않도록 설정할 수 있습니다.

하루 천만 건의 푸시 알림, 백만 건의 SMS, 5백만 건의 이메일을 처리할 수 있어야합니다.

 

필수 컴포넌트 이해하기

 

알림을 전송하기 위해서는 세 가지 컴포넌트에 대해 알아야합니다.

 

알림 제공자(provider)

알림을 요청하는 주체입니다.

각 단말에 적합한 API를 사용하여 알림을 전달합니다.

API 요청에는 단말을 식별할 수 있는 토큰과 알림의 내용을 담은 페이로드가 필요합니다.

 

알림 서비스(API)

제공자로부터 받은 알림을 단말기까지 전송하는 역할을 합니다.

IOS 단말은 APNS 알림 서비스를 이용하고 안드로이드는 FCM을 사용합니다.

SMS는 트윌리오나 넥스모같은 third pary 서비스를 사용합니다.

이메일은 Sendgrid, Mailchimp 등의 서비스가 있습니다.

 

단말기

알림을 받는 대상입니다.

사용자는 여러 단말기를 가질 수 있으므로 토큰으로 식별됩니다.

 

다음 그림은 각 단말에 대응되는 API 입니다.

 

개략적인 설계안

 

위에서 언급한 세 가지 컴포넌트를 포함하는, 단 하나의 서버로 구성된 알림 시스템입니다.

여러 분산 서버에 의해 알림이 발생된다고 가정하겠습니다. (혹은 마이크로서비스 아키텍쳐)

알림이 필요하면, 각 서비스는 알림 시스템에 요청합니다. 이 때, 알림 시스템은 컴포넌트 중에 알림 제공자의 역할을 합니다.

알림 시스템은 각 단말에 필요한 페이로드를 생성하고 API 요청을 보냅니다.

 

위 설계안은 다음의 문제를 포함하고 있습니다.

 

첫 설계안의 문제

 

SPOF

단일 서버이기 때문에 장애 발생 시에 전체 서비스 장애로 이어집니다.

 

규모 확장성

단일 계층으로, 여러 컴포넌트를 확장할 수 없습니다.

 

성능 병목

시스템이 과부하 상태에 빠지기 쉽습니다.

 

개선된 설계안

 

위 문제를 해결하기 위해서,

데이터 계층을 나누고, 캐시를 추가합니다.

서버를 증설하고 수평적 규모 확장이 가능하도록 합니다.

 

 

개선된 설계안에서 주목해야 할 점은 각 단말기에 메세지 큐와 작업 서버를 할당한 부분입니다.

메세지 큐를 사용하면 컴포넌트 사이의 강한 결합을 끊습니다. 또한 다량의 알림의 버퍼 역할을 할 수 있습니다.

그리고 각 단말기마다 종류 별로 할당했기 때문에 한 서비스에서 장애가 나도 다른 서비스에는 영향을 주지 않습니다.

 

좀 더 들어가기

 

안정성

알림 시스템의 가장 중요한 기능 중에 하나는 알림이 소실되면 안 된다는 것입니다.

이를 방지하기 위해서 시스템은 알림을 데이터베이스에 보관하고 전송에 실패할 경우 재시도 기능을 구현해야 합니다.

재시도 기능은 작업 서버가 메세지 큐로부터 받은 알림이 정상적으로 처리되지 않았을 경우, 다시 메세지 큐에 넣어 해결합니다.

만약, 이 과정이 여러 번 지속된다면 개발자에게 알릴 수 있도록 설계해야 합니다.

또한, 알림이 여러 번 전송되는 것을 방지해야 합니다. 알림에 포함하고자 하는 이벤트의 id를 기록하여 작업 서버에서 관리합니다.

 

큐 모니터링

알림 시스템에서 반드시 모니터링 해야하는 부분은 큐에 쌓인 알림의 개수입니다.

큐에 쌓인 알림의 개수를 통해 작업 서버 증설을 고려할 수 있습니다.

 

출처

 

가상 면접 사례로 배우는 대규모 시스템 설계 기초 - 인사이트