BackEnd/Kafka

[Kafka] Dead Letter Topic

연향동큰손 2025. 8. 14. 23:13

 

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정첵이 필요한 이유>

  1. 실패한 메시지를 저장하여 처리가 안된 메시지의 유실 방지
  2. DLT 토픽에 실패한 메시지를 저장하여 사후에 실패 원인 분석
  3. 처리되지 못한 메시지를 수동으로 처리할 수 있다.

 

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