티스토리 뷰
아모르각코 프로젝트에 코드 리뷰어로서 참여하고 있으며, 요청을 받아 시스템 설계를 돕기로 했다.
백엔드 개발자 분과 함께 고민하며 알림 시스템을 설계한 과정을 소개해보고자 한다.
참고로 서비스에서 알림은 총 6가지 케이스에 발송되며 주변 모각코 생성시 알림, 모각코 참여 수락 알림 등이다.
흐름은 다음과 같다:
1. 요구사항 파악
2. 고려할 케이스 파악
3. 기술 선택
4. 데이터 흐름 설계
5. 전체 아키텍처
1. 요구사항 파악
- 지원하는 알림 종류(email, sms, app push 등) 및 지원하는 기기 종류
- 서비스 상에서 알림 전송
- SMS 알림, 푸시 알림
- 현재 클라이언트는 웹 브라우저만 지원
- 실시간성의 수준
- 무조건 실시간은 아니어도 되지만, 가능하면 빠르게 전송
- 알림이 어떤 경우에 발송되는가
- 클라이언트의 API 호출시 (비정기적으로) 알림 발송
- 사용자가 알림을 받지 않도록 설정 가능한가
- ON/OFF 가능하도록 설정 제공
- 처리량은 어느정도인가 (설계 단계의 예상 수치)
- DAU: 5000명
- 동시 최대 요청 개수: 500개
[결과]
1. 처리량을 고려해 서비스 서버와 알림 서버를 분리한다.
2. 서비스 서버와 알림 서버는 MQ를 통해 데이터를 주고 받는다.
3. 두 종류의 알림은 각 다른 큐를 사용한다.
4. 각 큐는 소비자 그룹을 사용하여 처리량을 높인다.
2. 고려할 케이스 파악
- MQ 활용 고려 케이스
- 알림 발송이 누락되는 경우
- 알림이 한 번 (혹은 그 이상으로) 중복 발송되는 경우를 방지해야 한다.
- 무한 재시도 또한 방지해야 한다.
- 알림 발송에서 read-timeout 등의 이유로 발송됐지만 실패로 인식되는 경우 파악 필요
- 클릭이 한 번에 여러번 인식되는 등의 이유로 동시에 여러번 요청이 오는 경우
- 이 부분은 클라이언트에서 처리하도록 한다.
- 알림 발송이 누락되는 경우
- 예외 상황
- 알림 발송이 특정 시점에 몰리는 경우가 있는지
- 사용자가 악의로 알림을 계속 발송하게 할 수 있는지
[결과]
1. MQ는 데드레터를 사용한다. 시도 횟수를 저장하여 특정 횟수를 넘어가면 다시 큐에 넣는 작업을 멈춘다.
2. read-timeout 관련 예외 케이스는 해결 방법을 고민 중이다. 알림 서비스들이 제공해주는 기능이 있는지 살펴봐야 한다.
3. 서비스 서버와 알림 서버는 각각 수평 확장이 가능하도록 구성한다.
4. MQ의 소비자 그룹 개수를 동적으로 관리하는 방안을 고려한다.
3. 기술 선택
- 알림은 SMS와 푸시 알림을 사용하며, 푸시 알림은 FCM을 사용한다.
- MQ에 대해 고민해야 한다. 기능적으로 다음과 같은 분석이 있었다.
- Redis
- 데드레터를 직접 구현하여 사용해야 하며, Pub/Sub이나 List를 큐로 사용하면 소비자 그룹을 구성하기 어려움이 있다.
- RabbitMQ
- 데드레터나 소비자 그룹을 사용 가능하다.
- Kafka
- 데드레터나 소비자 그룹을 사용 가능하다.
- Redis
- 맨 처음에는 가장 가벼운 Redis가 어떤가 싶었지만, 기능적 불편함이 있었다.
- RabbitMQ와 Kafka 중 RabbitMQ를 선택한 이유는 다음과 같다.
- Kafka를 사용해서 모든 내역이 기록될 이유가 없었으며, 요구되는 처리량이 Kafka를 사용할 만큼도 아니었다.
- RabbitMQ를 사용해도 무리없이 처리량을 만족하며 원하는 기능들을 사용할 수 있었다.
- 백엔드 개발자 분께서 Kafka에 대해 깊은 이해도가 없는 상황에서 굳이 Kafka를 사용하며 새로운 내용을 학습할 이유도 없었다.
[결과]
1. MQ는 RabbitMQ를 사용한다.
4. 데이터 흐름 설계
1. 사용자의 요청시 관련 데이터를 알림 테이블에 저장 후 페이로드를 MQ의 큐에 넣기
2. 소비자 그룹 중 한 Consumer는 데이터를 가져와 알림 발송
2-1. 실패시 dlq로 들어가며 실패한 데이터로 상태 업데이트하며 시도 횟수 증가시켜 업데이트
2-2. 일정 주기로 스케줄링을 통해 아직 완료되지 않은 상태의 데이터 가져와 큐에 다시 넣음
2-3. 일정 횟수 실패한 알림 데이터는 완전히 실패한 상태 업데이트 및 관리자 슬랙으로 알림 발송
3. 관리자는 완전히 실패한 상태의 알림 데이터의 id를 슬랙에서 확인하여 관리자 권한의 API를 통해 다시 큐에 넣을 수 있으며, 혹은 DB를 확인하여 에러 이유를 파악함
5. 전체 아키텍처
(아직 테스트해볼 부분이 있기에 아키텍처를 그려놓지 않았다. 완료되면 추가하겠다.)
결론
이러한 과정으로 설계를 마쳐 현재 기능 개발 중에 있다. 수치적인 부분들은 예상으로 산정한 부분이 많기에 테스트해보며 개선하기로 했다.
추가 진행 현황: 지도에서 위치 기반으로 주변 모각코를 검색하는 기능 또한 설계 중이며, 완료시 포스트하겠다.