실시간 채팅에 메시지 유실 해결법은...?🤔

의혁·2025년 4월 1일
0

[Kafka] 카프카 학습

목록 보기
6/6
post-thumbnail

💡 MSA 기반 Kafka를 통한 채팅 서비스의 메시지 유실 막아보자!! 💪🏻

1. 개요 위와 동일한 구조로 MSA 구조의 Kafka 기반 실시간 채팅 서비스를 구현하였다.

동작방식은 아래와 같다
1. Client가 메시지 전송 (sendMessage 메소드 실행)
2. DB에 메시지 전송
3. Kafka Producer를 통해 메시지를 Kafka Broker로 전송
4. KafkA Consumer가 Broker에서 본인에게 해당하는 메시지 가져옴
5. Stomp를 통해서 해당 채팅방을 구독중인 Client에게 전송

하지만, 만약 전송한 메시지가 "유실"된다면??

만약 메시지가 유실된다면, 실시간 채팅 서비스에서 메시지가 유실된다면, 실제로 전송하는 사용자와 받는 사용자의 메시지가 달라져서 "원자성"이 꺠지는 문제가 발생하게 된다.
따라서, 신뢰성 측면에서도 DB에 저장되는 메시지와 kafka를 통해 전송하는 메시지가 일치해야한다.


2. 문제 원인

메시지가 유실될 경우는 총 2가지가 존재한다. ( 위사진의 1번과 2번을 참고하여 보자)

1. 전송한 메시지한 메시지가 DB에는 잘 저장되지만, Kafka Broker에는 제대로 전송되지 않음

2. Kafka Broker에는 이벤트가 잘 전송되었지만, DB에는 제대로 전송되지 않음

위와 같은 경우에는 "원자성"이 지켜지지 않기 때문에, 신뢰성을 보장해줘야 한다.


3. 실제 예시

1) 성공 예시

위 처럼 Kafka 서버가 잘 띄워 져 있는 경우에는 메시지도 잘 전송되고, Consumer도 이벤트를 잘 받아서 처리하는 것을 볼 수 있다.

2) 실패 예시

만약 어떠한 오류로 인해 Kafka의 연결이 끊어지게 된다면, Producer에 의해 메시지가 전달되어도, Consumer는 아무것도 받지 못하고, 오류를 발생시킨다.
또한 실시간 채팅 서비스 관점에서 봤을때도, 메시지 전송은 되었지만, 받는 사람은 메시지 전송을 실시간으로 받지 못하고,
"해당 메시지가 유실" 된 것으로 볼수있다.

물론, Retry 방식이나 ACk을 통해서 재 전송을 요청할 수 있지만, 만일 Retry를 3번 시도한 후에도, Ack이 계속 전송이 안되는 경우에는 결국 아예 메시지가 유실되게 된다.

따라서, 다른 방식을 통해 메시지 유실을 방지하여, "원자성"을 유지해야한다.


4. 해결 방법

1) Outbox 패턴 적용

+) Outbox는 @Transactional을 필수로 하기 때문에, MongoDB의 @Transactional 처리를 위한 replica-set을 설정하였다. (2번 참고)


참고 블로그
1.
2. MongoDB Replica-set 설정

profile
매일매일 차근차근 나아가보는 개발일기

0개의 댓글