[Project] 알림 서비스 기술적 의사 결정

김지현·2025년 4월 10일
0

Spring Boot 프로젝트

목록 보기
22/24

기획

이번 프로젝트는 라이더용 배달 어플로, 주문이 발생하면 가게 근처의 라이더들에게 주문 배달 알림을 전송하는 기능을 구현해야한다. 이 때, 이 알림 기능을 어떤 기술로 구현할지에 대해 고민해보았다.

메시지 큐

우선 이번 알림 서비스 구현은 이벤트 기반의 메시지 큐를 활용하여 구현하기로 결정했다. 메시지 큐 활용시 알림 서비스가 비동기적으로 실행되어 빠르고 안정적으로 처리될 수 있을 뿐만 아니라 시스템 간의 결합도를 낮춰 유지보수와 확장에 용이하기 때문이다.

그렇다면 메시지 큐를 어떤 기술로 구현할 것인가에 대한 고민을 하게 되었는데 가장 일반적인 메시지 큐인 RabbitMQ, kafka와 Redis Pub/Sub까지 함께 고려해보았다.

Redis Pub/Sub

Redis Pub/Sub은 큐에 메시지를 저장하는 형태가 아닌, 메시지 발행과 함께 구독자들에게 즉시 전달 후 소멸되는 형태이다. 메시지가 저장되지 않으므로 메시지 전달에 대한 보장이 약하다. 즉 신뢰성이 떨어진다. 그렇지만 구현이 가장 간단하다.

Redis Pub/Sub은 실시간 처리에만 적합하고 알림 전달 보장이 필요한 시스템에서는 적합하지 않다고 할 수 있다. 우리 서비스는 라이더들에게 배달에 대한 알림 전송의 안정성이 중요하다고 볼 수 있으므로 Redis Pub/Sub은 고려 대상에서 제외하기로 결정했다.

RabbitMQ VS Kafka

RabbitMQ와 Kafka는 둘 다 발행된 메시지를 큐에 저장하는 방식이다. 전송에 실패하더라도 사용자가 알림을 다시 받을 수 있다. 즉 신뢰성 높은 메시지 처리가 가능하다.

RabbitMQ와 Kafka의 가장 큰 차이는 대용량 스트림인데 Kafka는 고용량 대용량 처리에 강하여 메시지 내구성이 매우 좋다. 다만 우리 서비스에서 한 번에 수십만건의 알림을 처리할 것도 아니고 단순 알림 서비스에 Kafka를 적용하기에는 구현 난이도, 비용, 스펙 측면에서 모두 과하다고 생각했기 때문에 RabbitMQ로 결정했다.

그러나 이 결정을 번복하게 되는데.... 이유는 이벤트를 발행하는 로직에서 이미 Kafka로 이벤트를 발행하고 있기 때문이었다. Kafka는 producer에서 이벤트를 한 번 발행하면 consumer쪽에서 group id를 다르게 설정하여 여러 다른 도메인에서 하나의 이벤트에 대해 각각 처리할 수 있다는 특징이 있다. 즉, 알림 쪽에서 RabbitMQ를 사용하게 되면 이벤트를 두 번 발행해야하지만, kafka를 사용하게 되면 추가적인 이벤트 발행 로직 없이 이미 발행된 이벤트를 활용하면 된다.

뿐만 아니라, 프로젝트 전반적으로 Kafka를 사용하고 있었으나 RabbitMQ를 사용하고 있는 도메인은 없다. 여기서 알림 기능에 RabbitMQ를 도입하게 되면 RabbitMQ 도커 컨테이너를 추가로 띄우고 설정해야하므로 추가적인 비용이 발생하게 된다.

이러한 이유로 Kafka로 통일하여 구현하기로 결정하였다.

클라이언트

처음에는 우리 서비스에 프론트가 존재하지 않아서 Slack 알림으로 구현하였다. 그러나 후에 WebSocket을 활용한 알림 기능도 구현하면 좋을 것 같아서 WebSocket Stomp를 활용해 두 가지 알림이 비동기로 전송될 수 있도록 구현하기로 결정햇다.

profile
Server Developer

0개의 댓글