Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka) · Les

Dead-lettertopics (DLT) implementeren

Configureer dead-lettertopics om berichten die herhaaldelijk niet kunnen worden verwerkt vast te leggen en op te slaan, zodat ze later kunnen worden geanalyseerd en opnieuw verwerkt.

Les 3 van 411 stappen

Dead-lettertopics (DLT) implementeren is een gratis Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka)-les op CoddyKit. Dit is les 3 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka). Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka) bevat in totaal 4 lessen.

Waarom Dead Letter Topics?

In gebeurtenisgestuurde systemen lukt het consumers soms niet om berichten te verwerken door tijdelijke fouten, bijvoorbeeld wanneer een database niet beschikbaar is, of door permanente problemen, zoals beschadigde gegevens.

  • Wat gebeurt er met deze mislukte berichten?
  • Proberen we ze onbeperkt opnieuw, waardoor de wachtrij wordt geblokkeerd?
  • Of verwijderen we ze, waardoor mogelijk belangrijke gegevens verloren gaan?

Daar komen Dead Letter Topics (DLT's) van pas!

Wat is een Dead Letter Topic?

Een Dead Letter Topic (DLT) is een speciaal Kafka-topic waar berichten naartoe worden gestuurd waarvan de verwerking herhaaldelijk mislukt.

  • Het fungeert als een 'quarantaine' voor problematische berichten.
  • In plaats van de hoofdconsumer te blokkeren of gegevens te verliezen, worden berichten naar de DLT verplaatst.
  • Zo kan de hoofdconsumer nieuwe berichten blijven verwerken.

Berichten in een DLT kunnen vervolgens worden geïnspecteerd, handmatig gecorrigeerd of later opnieuw worden verwerkt.

DLT-ondersteuning van Spring Kafka

Spring for Apache Kafka biedt uitstekende ondersteuning voor DLT's via zijn mechanismen voor foutafhandeling.

Het belangrijkste onderdeel is de DefaultErrorHandler, die zo kan worden geconfigureerd dat mislukte berichten na een bepaald aantal nieuwe pogingen naar een DLT worden gepubliceerd.

Intern gebruikt deze een DeadLetterPublishingRecoverer om de daadwerkelijke publicatie uit te voeren.

Basisconfiguratie voor DLT

Om DLT in te schakelen voor een @KafkaListener, kun je de DefaultErrorHandler configureren met een DeadLetterPublishingRecoverer. In dit voorbeeld wordt na 3 afleverpogingen een eenvoudige DLT ingesteld.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.listener.DeadLetterPublishingRecoverer;
import org.springframework.kafka.listener.DefaultErrorHandler;
import org.springframework.util.backoff.FixedBackOff;

@SpringBootApplication
public class DltApplication {

  public static void main(String[] args) {
    SpringApplication.run(DltApplication.class, args);
  }

  @Bean
  public DefaultErrorHandler errorHandler(KafkaTemplate<?, ?> kafkaTemplate) {
    // Publish to DLT after 3 delivery attempts
    // FixedBackOff(interval, maxAttempts) -> interval is ignored for DLT after retries
    return new DefaultErrorHandler(new DeadLetterPublishingRecoverer(kafkaTemplate),
                                   new FixedBackOff(0L, 2L)); // 0L interval, 2 retries = 3 attempts total
  }

  @KafkaListener(topics = "my-main-topic", groupId = "my-group", errorHandler = "errorHandler")
  public void listen(String message) {
    System.out.println("Received: " + message);
    if (message.contains("fail")) {
      throw new RuntimeException("Simulating processing failure!");
    }
  }

  // To send messages for testing (not part of DLT config itself)
  // @Autowired
  // private KafkaTemplate<String, String> template;
  // @EventListener(ApplicationReadyEvent.class)
  // public void sendMessage() {
  //   template.send("my-main-topic", "Hello");
  //   template.send("my-main-topic", "This will fail");
  // }
}

Namen van DLT-topics begrijpen

Standaard geeft Spring Kafka het DLT-topic een naam door .DLT toe te voegen aan de naam van het oorspronkelijke topic. Als je hoofdtopic bijvoorbeeld my-main-topic heet, wordt de DLT my-main-topic.DLT.

  • Je kunt dit gedrag aanpassen.
  • De constructor van DeadLetterPublishingRecoverer kan een BiFunction ontvangen om het DLT-topic en de partitie te bepalen.
  • Zo kun je flexibelere naamgevingsconventies gebruiken of mislukte berichten op basis van criteria naar verschillende DLT's routeren.

Berichtheaders in een DLT

Wanneer een bericht naar een DLT wordt gestuurd, voegt Spring Kafka er verschillende nuttige headers aan toe. Deze headers geven context over de reden waarom het bericht in de DLT is beland:

  • dlt_exception-fqcn: Volledig gekwalificeerde klassenaam van de exception.
  • dlt_exception-message: Bericht van de exception.
  • dlt_exception-stacktrace: Volledige stacktrace.
  • dlt_original-topic: Het topic waar het bericht vandaan kwam.
  • dlt_original-partition: De oorspronkelijke partitie.
  • dlt_original-offset: De oorspronkelijke offset.

Deze headers zijn onmisbaar voor foutopsporing en het opnieuw verwerken van berichten.

Publicatie van DLT's aanpassen

Je kunt een aangepaste DeadLetterPublishingRecoverer opgeven voor gedetailleerde controle over hoe berichten naar de DLT worden gepubliceerd. Zo kun je headers aanpassen, berichten filteren of zelfs voorkomen dat bepaalde berichten naar de DLT gaan.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.listener.DeadLetterPublishingRecoverer;
import org.springframework.kafka.listener.DefaultErrorHandler;
import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.backoff.FixedBackOff;

@SpringBootApplication
public class CustomDltApplication {

  public static void main(String[] args) {
    SpringApplication.run(CustomDltApplication.class, args);
  }

  @Bean
  public DefaultErrorHandler customErrorHandler(KafkaTemplate<Object, Object> kafkaTemplate) {
    DeadLetterPublishingRecoverer customRecoverer = new DeadLetterPublishingRecoverer(kafkaTemplate,
      (record, exception) -> { // Custom DLT topic/partition resolver
        System.out.println("Sending to DLT: " + record.topic() + ".custom.dlt");
        return new DeadLetterPublishingRecoverer.HeaderNames(record.topic() + ".custom.dlt", null);
      });
    return new DefaultErrorHandler(customRecoverer, new FixedBackOff(0L, 1L)); // 1 retry = 2 attempts total
  }

  @KafkaListener(topics = "another-topic", groupId = "my-custom-group", errorHandler = "customErrorHandler")
  public void listenWithCustomDlt(String message) {
    System.out.println("Received (custom DLT): " + message);
    if (message.contains("fail")) {
      throw new RuntimeException("Simulating custom DLT failure!");
    }
  }
}

DLT-berichten consumeren

Zodra berichten in een DLT staan, heb je een andere consumer nodig om ze te verwerken. Deze DLT-consumer kan worden ontworpen om:

  • De fout te loggen en beheerders op de hoogte te brengen.
  • Het bericht in een database op te slaan voor handmatige beoordeling.
  • Te proberen het bericht na een vertraging of transformatie opnieuw te verwerken.

Het is gewoon nog een @KafkaListener, maar dan geconfigureerd om naar het DLT-topic te luisteren.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.listener.DeadLetterPublishingRecoverer;
import org.springframework.kafka.listener.DefaultErrorHandler;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.util.backoff.FixedBackOff;

@SpringBootApplication
public class DltConsumerApplication {

  public static void main(String[] args) {
    SpringApplication.run(DltConsumerApplication.class, args);
  }

  @Bean
  public DefaultErrorHandler errorHandler(KafkaTemplate<?, ?> kafkaTemplate) {
    return new DefaultErrorHandler(new DeadLetterPublishingRecoverer(kafkaTemplate),
                                   new FixedBackOff(0L, 2L));
  }

  @KafkaListener(topics = "my-main-topic", groupId = "my-group", errorHandler = "errorHandler")
  public void listenMain(String message) {
    System.out.println("Main Listener Received: " + message);
    if (message.contains("fail")) {
      throw new RuntimeException("Main processing failure!");
    }
  }

  @KafkaListener(topics = "my-main-topic.DLT", groupId = "dlt-group")
  public void listenDlt(String message,
                        @Header(KafkaHeaders.RECEIVED_TOPIC) String receivedTopic,
                        @Header(KafkaHeaders.ORIGINAL_OFFSET) Long originalOffset,
                        @Header(KafkaHeaders.EXCEPTION_MESSAGE) String exceptionMessage) {
    System.out.println("DLT Listener Received: " + message);
    System.out.println("  From Topic: " + receivedTopic);
    System.out.println("  Original Offset: " + originalOffset);
    System.out.println("  Exception: " + exceptionMessage);
    // Here you would implement logic to store, alert, or reprocess
  }
}

Aanbevolen werkwijzen voor DLT's

Overweeg de volgende aanbevolen werkwijzen om DLT's effectief te gebruiken:

  • Houd DLT's in de gaten: Stel waarschuwingen in voor berichten die in DLT's verschijnen, omdat ze op aanhoudende problemen wijzen.
  • Verwerk DLT's: Laat DLT's niet onbeperkt groeien. Zorg voor een plan om deze berichten te consumeren en af te handelen.
  • Idempotentie: Zorg ervoor dat je logica voor het opnieuw verwerken van DLT-berichten idempotent is, om problemen door dubbele verwerking te voorkomen.
  • Scheid verantwoordelijkheden: Houd DLT-consumers gescheiden van je hoofdlogica, zodat verantwoordelijkheden duidelijker zijn.
  • Schema-evolutie: Houd rekening met schemawijzigingen bij het opnieuw verwerken van oude DLT-berichten.

Snelle DLT-controle

Wat is het belangrijkste voordeel van het gebruik van een Dead Letter Topic (DLT) in een Kafka-consumerapplicatie?

Samenvatting: DLT voor robuustheid

Je hebt geleerd dat Dead Letter Topics een cruciaal onderdeel zijn van robuuste en veerkrachtige Kafka-consumerapplicaties.

  • DLT's isoleren berichten waarvan de herhaalde verwerking mislukt.
  • De DefaultErrorHandler en DeadLetterPublishingRecoverer van Spring Kafka vereenvoudigen de integratie met DLT's.
  • Berichten die naar DLT's worden gestuurd, bevatten nuttige headers voor foutopsporing.
  • DLT's hebben een aparte consumer nodig om de mislukte berichten af te handelen.

Door DLT's te implementeren, zorg je ervoor dat je consumers fouten gecontroleerd kunnen afhandelen, gegevensverlies voorkomen en de berichtenstroom stabiel houden.

Gratis beginnen

Leer Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka) met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
12
Lessen
48

Veelgestelde vragen

Is de les “Dead-lettertopics (DLT) implementeren” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka), waaronder “Dead-lettertopics (DLT) implementeren”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka) bevat in totaal 4 lessen.

Wat leer ik in “Dead-lettertopics (DLT) implementeren”?

Configureer dead-lettertopics om berichten die herhaaldelijk niet kunnen worden verwerkt vast te leggen en op te slaan, zodat ze later kunnen worden geanalyseerd en opnieuw verwerkt. Je oefent met Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka) door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka) te beginnen?

Ervaring vooraf is niet nodig. Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka) op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Dead-lettertopics (DLT) implementeren”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka)?

Ja. Elke les over Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka) bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Consumeruitzonderingen afhandelen
  2. Retrymechanismen met Spring Retry
  3. Dead-lettertopics (DLT) implementeren
  4. Niet-blokkerende retries met retry topics
← Terug naar Geavanceerd Spring Boot 4: gebeurtenisgestuurde architectuur (Kafka)