Producer에서 메시지를 Kafka로 전송하고 Consumer가 처리를 해야하는데 Consumer에서 메시지를 처리하지 못하게 되면 어떻게 될까?
Kafka에서는 재시도(Retry)정책을 통해 메시지 처리에 실패 했을때 적절한 대응이 가능하다.
재전송과 관련된 정책은 @RetryableTopic에서 정의할 수 있다.
- attempts : 재전송 시도 횟수
- backoff : 재전송 시간 간격 정의, multiplier를 2로 정의할 경우 재전송 간격이 2배씩 증가.
- dltTopicSufflix : dlt Topic의 접미사 정의
@KafkaListener(
topics = "email.send",
groupId = "email-send-group"
)
@RetryableTopic(
attempts = "5",
backoff = @Backoff(delay = 1000, multiplier = 2), // 1000 -> 2000 -> 4000 ......
//email.send.dlt
dltTopicSuffix = ".dlt"
)
public void consume(String message){
System.out.println("Kafka로부터 받아온 메시지 : " + message);
EmailSendMessage emailSendMessage = EmailSendMessage.fromJson(message);
System.out.println("받은 to 값: [" + emailSendMessage.getTo() + "]");
if (emailSendMessage.getTo().equals("fail@naver.com")) {
System.out.println("잘못된 이메일 주소로 인해 발송 실패");
throw new RuntimeException("잘못된 이메일 주소로 인해 발송 실패");
}
// 실제 이메일 발송 로직 생략
try {
Thread.sleep(3000);
}catch (InterruptedException e){
throw new RuntimeException("이메일 발송 실패");
}
System.out.println("이메일 발송 완료");
}
Consumer의 콘솔창을 확인해보면 재시도에 관한 정보를 확인 가능하다.
Kafka로부터 받아온 메시지 : {"from":"내용10","to":"fail@naver.com","subject":"제목10","body":"sender@naver.com"}
받은 to 값: [fail@naver.com]
잘못된 이메일 주소로 인해 발송 실패
2025-08-14T22:57:35.560+09:00 INFO 61167 --- [etry-2000-0-C-1] o.a.k.c.c.i.ClassicKafkaConsumer : [Consumer clientId=consumer-email-send-group-retry-2000-1, groupId=email-send-group-retry-2000] Seeking to offset 4 for partition email.send-retry-2000-0
2025-08-14T22:57:35.560+09:00 INFO 61167 --- [etry-2000-0-C-1] o.s.k.l.KafkaMessageListenerContainer : Record in retry and not yet recovered
Kafka로부터 받아온 메시지 : {"from":"내용10","to":"fail@naver.com","subject":"제목10","body":"sender@naver.com"}
받은 to 값: [fail@naver.com]
잘못된 이메일 주소로 인해 발송 실패
2025-08-14T22:57:37.680+09:00 INFO 61167 --- [etry-4000-0-C-1] o.a.k.c.c.i.ClassicKafkaConsumer : [Consumer clientId=consumer-email-send-group-retry-4000-5, groupId=email-send-group-retry-4000] Seeking to offset 4 for partition email.send-retry-4000-0
2025-08-14T22:57:37.681+09:00 INFO 61167 --- [etry-4000-0-C-1] o.s.k.l.KafkaMessageListenerContainer : Record in retry and not yet recovered
Kafka로부터 받아온 메시지 : {"from":"내용10","to":"fail@naver.com","subject":"제목10","body":"sender@naver.com"}
받은 to 값: [fail@naver.com]
잘못된 이메일 주소로 인해 발송 실패
2025-08-14T22:57:41.621+09:00 INFO 61167 --- [etry-8000-0-C-1] o.a.k.c.c.i.ClassicKafkaConsumer : [Consumer clientId=consumer-email-send-group-retry-8000-3, groupId=email-send-group-retry-8000] Seeking to offset 4 for partition email.send-retry-8000-0
2025-08-14T22:57:41.621+09:00 INFO 61167 --- [etry-8000-0-C-1] o.s.k.l.KafkaMessageListenerContainer : Record in retry and not yet recovered
Kafka로부터 받아온 메시지 : {"from":"내용10","to":"fail@naver.com","subject":"제목10","body":"sender@naver.com"}
받은 to 값: [fail@naver.com]
잘못된 이메일 주소로 인해 발송 실패
2025-08-14T22:57:49.101+09:00 ERROR 61167 --- [etry-8000-0-C-1] k.r.DeadLetterPublishingRecovererFactory : Record: topic = email.send-retry-8000, partition = 0, offset = 4, main topic = email.send threw an error at topic email.send-retry-8000 and won't be retried. Sending to DLT with name email.send.dlt.
Dead Letter Topic
DLT(Dead Letter Topic)는 오류로 인해 처리할 수 없는 메시지를 임시로 저장하는 토픽이다.
<DLT정첵이 필요한 이유>
- 실패한 메시지를 저장하여 처리가 안된 메시지의 유실 방지
- DLT 토픽에 실패한 메시지를 저장하여 사후에 실패 원인 분석
- 처리되지 못한 메시지를 수동으로 처리할 수 있다.
Kafka Server에서 DLT에 저장된 메시지를 정말 저장하고 있는지 확인 해봤다.
$ bin/kafka-console-consumer.sh \
--bootstrap-server localhost:9092 \
--topic email.send.dlt \
--from-beginning
'BackEnd > Kafka' 카테고리의 다른 글
[Kafka] Kafka 메시지 처리 성능 향상 (Partition) (0) | 2025.08.15 |
---|---|
Spring Boot + Kafka 메시지 테스트 (2) | 2025.08.14 |
Kafka란? (1) | 2025.08.12 |