Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka) · Lektion

Implementera dead-letter-topics (DLT)

Konfigurera dead-letter-topics för att fånga upp och lagra meddelanden som upprepade gånger misslyckas, så att de senare kan analyseras och bearbetas igen.

Lektion 3 av 411 steg

Implementera dead-letter-topics (DLT) är en gratis lektion i Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka) på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka), och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka) innehåller totalt 4 lektioner.

Varför Dead Letter Topics?

I händelsestyrda system misslyckas konsumenter ibland med att bearbeta meddelanden på grund av övergående fel, till exempel att databasen är otillgänglig, eller permanenta problem, till exempel felaktigt formaterade data.

  • Vad händer med dessa misslyckade meddelanden?
  • Försöker vi bearbeta dem igen för alltid och blockerar kön?
  • Eller kastar vi bort dem och riskerar att förlora kritiska data?

Det är här Dead Letter Topics (DLT:er) kommer in i bilden!

Vad är ett Dead Letter Topic?

Ett Dead Letter Topic (DLT) är ett särskilt Kafka-topic dit meddelanden som upprepade gånger misslyckas med att bearbetas skickas.

  • Det fungerar som en "karantän" för problematiska meddelanden.
  • I stället för att blockera huvudkonsumenten eller förlora data flyttas meddelandena till DLT:n.
  • Det gör att huvudkonsumenten kan fortsätta bearbeta nya meddelanden.

Meddelanden i en DLT kan sedan granskas, korrigeras manuellt eller bearbetas igen senare.

Spring Kafkas stöd för DLT

Spring for Apache Kafka erbjuder utmärkt stöd för DLT:er genom sina mekanismer för felhantering.

Den centrala komponenten är DefaultErrorHandler, som kan konfigureras för att publicera misslyckade meddelanden till en DLT efter ett visst antal återförsök.

Internt använder den en DeadLetterPublishingRecoverer för att utföra själva publiceringen.

Grundläggande DLT-konfiguration

För att aktivera DLT för en @KafkaListener kan du konfigurera DefaultErrorHandler med en DeadLetterPublishingRecoverer. Det här exemplet konfigurerar en enkel DLT efter tre leveransförsök.

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");
  // }
}

Förstå namn på DLT-topics

Som standard namnger Spring Kafka DLT:n genom att lägga till .DLT i slutet av det ursprungliga topic-namnet. Om ditt huvudtopic till exempel är my-main-topic blir DLT:n my-main-topic.DLT.

  • Du kan anpassa detta beteende.
  • Konstruktorn för DeadLetterPublishingRecoverer kan ta emot en BiFunction som avgör DLT-topic och partition.
  • Det ger mer flexibla namnkonventioner och gör det möjligt att dirigera misslyckade meddelanden till olika DLT:er baserat på kriterier.

Meddandeheaders i DLT

När ett meddelande skickas till en DLT lägger Spring Kafka till flera användbara headers. Dessa headers ger information om varför meddelandet hamnade i DLT:n:

  • dlt_exception-fqcn: Undantagets fullständigt kvalificerade klassnamn.
  • dlt_exception-message: Meddelandet från undantaget.
  • dlt_exception-stacktrace: Hela stacktracen.
  • dlt_original-topic: Topicet som meddelandet kom från.
  • dlt_original-partition: Den ursprungliga partitionen.
  • dlt_original-offset: Den ursprungliga offseten.

Dessa headers är ovärderliga vid felsökning och ombearbetning.

Anpassa DLT-publicering

Du kan ange en anpassad DeadLetterPublishingRecoverer för att få detaljerad kontroll över hur meddelanden publiceras till DLT. Det gör att du kan ändra headers, filtrera meddelanden eller till och med förhindra att vissa meddelanden skickas till DLT.

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!");
    }
  }
}

Konsumera DLT-meddelanden

När meddelanden väl finns i en DLT behöver du en annan konsument som behandlar dem. Den här DLT-konsumenten kan utformas för att:

  • Logga felet och meddela administratörer.
  • Lagra meddelandet i en databas för manuell granskning.
  • Försöka behandla meddelandet igen efter en fördröjning eller transformering.

Det är helt enkelt ytterligare en @KafkaListener, men konfigurerad för att lyssna på DLT-ämnet.

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
  }
}

Bästa praxis för DLT

Överväg följande bästa praxis för att använda DLT:er effektivt:

  • Övervaka DLT:er: Konfigurera aviseringar för meddelanden som hamnar i DLT:er, eftersom de indikerar ihållande problem.
  • Behandla DLT:er: Låt inte DLT:er växa utan begränsning. Ha en plan för att konsumera och hantera dessa meddelanden.
  • Idempotens: Säkerställ att logiken för ombehandling från DLT är idempotent för att undvika problem med duplicerad behandling.
  • Separera ansvarsområden: Håll DLT-konsumenter åtskilda från programmets huvudsakliga logik för tydligare ansvarsområden.
  • Schemautveckling: Var uppmärksam på schemaändringar när gamla DLT-meddelanden behandlas igen.

Snabbkontroll av DLT

Vilken av följande är den främsta fördelen med att använda ett Dead Letter Topic (DLT) i en Kafka-konsumentapplikation?

Sammanfattning: DLT för robusthet

Du har lärt dig att Dead Letter Topics är en viktig komponent för att bygga robusta och motståndskraftiga Kafka-konsumentapplikationer.

  • DLT:er isolerar meddelanden som misslyckas vid upprepad behandling.
  • Spring Kafka:s DefaultErrorHandler och DeadLetterPublishingRecoverer förenklar integreringen av DLT.
  • Meddelanden som skickas till DLT:er innehåller användbara headers för felsökning.
  • DLT:er kräver en separat konsument som hanterar de misslyckade meddelandena.

Genom att implementera DLT:er säkerställer du att dina konsumenter kan hantera fel på ett kontrollerat sätt, förhindra dataförlust och upprätthålla ett jämnt meddelandeflöde.

Gratis att börja

Lär dig Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka) med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
12
Lektioner
48

Vanliga frågor

Är lektionen ”Implementera dead-letter-topics (DLT)” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka), inklusive ”Implementera dead-letter-topics (DLT)”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka) innehåller totalt 4 lektioner.

Vad lär jag mig i ”Implementera dead-letter-topics (DLT)”?

Konfigurera dead-letter-topics för att fånga upp och lagra meddelanden som upprepade gånger misslyckas, så att de senare kan analyseras och bearbetas igen. Ni övar på Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka) med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka)?

Du behöver inga förkunskaper. Utbildningen i Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka) på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Implementera dead-letter-topics (DLT)”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka)-lektionen?

Ja. Varje Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka)-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Hantera konsumentundantag
  2. Mekanismer för återförsök med Spring Retry
  3. Implementera dead-letter-topics (DLT)
  4. Icke-blockerande omförsök med retry topics
← Tillbaka till Avancerad Spring Boot 4: händelsestyrd arkitektur (Kafka)