포폴/일정관리앱
일정알림기능2- 실시간 알림에 카프카를 사용이유
slown
2025. 5. 17. 14:28
목차
1.기존의 코드의 문제점
2.왜 Kafka를 사용을 했는가?
3.적용
4.후기
1.기존 코드의 문제점
현재 일정관리프로젝트에서는 스프링 이벤트 드라이븐을 사용해서 단일 인메모리 이벤트 처리로 후처리를 하고 있지만 해당 방식에는 다음과 같은 문제가 있습니다.
- 비동기 처리라 해도 같은 서버 내에서만 작동
→ 서버가 죽거나 장애가 발생하면 스프링 이벤트는 영속성이 없어서 유실이 된다는 점입니다. - 후처리 로직이 많아질수록 하나의 서비스에 부하 집중
- 서비스 간 확장 어려움
→ 향후 알림 시스템을 별도 분리하고자 할 때 제약이 됩니다.
결론적으로, 비동기 이벤트 처리의 영속성, 확장성, 결합도 측면에서 한계를 드러내기 시작했다.
2.왜 Kafka를 사용을 했는가?
카프카는 분산 메시징 시스템입니다. 물론 Kafka의 대안으로 RabbitMq도 있습니다만 다음과 같은 이유로 선택했습니다.
내결함성 (Fault Tolerance) | 메시지를 디스크에 저장 → 장애 상황에서도 복구 가능 |
비동기 + 비동기 큐잉 지원 | 메시지를 보내는 쪽과 받는 쪽이 완전히 분리됨 |
다중 소비자 확장 | 하나의 이벤트를 여러 서비스에서 구독 처리 가능 (예: 이메일, 알림, 로깅) |
확장성 | 메시지 양이 많아져도 브로커나 컨슈머만 늘리면 처리 가능 |
추가 기능 분리가 쉬움 | 예: notification-events 토픽에 새로운 컨슈머를 붙이기만 하면 됨 |
스프링 이벤트 기반의 구조는 로컬 수준의 단일 이벤트 처리에는 좋지만,
- 이벤트 유실 방지,
- 서비스 독립성과 확장성,
- 운영 환경에서의 장애 대응 을 고려했을 때, Kafka가 더 적합하다고 판단했다.
3.적용
기능 | 모듈 위치 | 이유 |
Kafka Consumer (알림 수신) | notification.connector.in-connector | Kafka에서 들어오는 메시지를 수신 → inbound 역할 |
알림 저장/발송 비즈니스 로직 | notification.core.service | 핵심 도메인 로직은 core에 위치해야 함 |
Notification Entity | notification.core.model | 알림 도메인 객체는 core의 책임 |
Kafka DTO | notification.connector.api-model | Kafka 외부 메시지에 대한 직렬화 모델이므로 connec |
그럼 위와 같이 적용을 하게 되면 아래의 그림처럼이 됩니다.
코드 흐름 요약
알림 발행 (Producer)
NotificationEvents notificationEvent = NotificationEvents.builder()
.receiverId(event.getMemberId())
.message("회원가입 완료 알림")
.notificationType("SIGN_UP")
.createdTime(LocalDateTime.now())
.build();
notificationEventProducer.sendNotification(notificationEvent);
알림 수신 (Consumer)
@KafkaListener(topics = "notification-events", groupId = "notification-group")
public void consume(NotificationEvents event) {
simpMessagingTemplate.convertAndSend(
"/topic/notifications/" + event.getReceiverId(),
objectMapper.writeValueAsString(event));
}
전체 구성 흐름
- 회원가입 이벤트 발생 → 알림 이벤트 생성
- Kafka Producer가 notification-events 토픽에 발행
- Consumer가 메시지를 수신 → WebSocket을 통해 실시간 알림 전송
- 동시에 DB에 알림 저장
4.후기
Kafka를 직접 알림 시스템에 적용해보면서 다음과 같은 효과를 체감할 수 있었다:
- 시스템 간 결합도가 낮아지면서, 새로운 알림 타입을 추가해도 기존 로직 수정이 거의 없음
- 장애 발생 시에도 Kafka 자체가 메시지를 버퍼링하기 때문에 실시간 처리가 안정적
- WebSocket, 이메일, DB저장 등 다양한 후처리를 병렬적으로 확장 가능
물론, Kafka 설정 자체는 간단하지 않고, 추후 DLQ, Outbox 패턴과 같은 운영/신뢰성 보완 작업이 필요합니다. 하지만 이번 적용을 통해 이벤트 드리븐 시스템을 좀 더 견고하게 확장할 수 있는 기반이 마련되었습니다. 추후에는 DLQ를 적용하고 이벤트의 보장성을 위해서 Outbox패턴을 적용을 할 예정입니다.