Spring boot 我想启用Kafka errorhandling by annotation

Spring boot 我想启用Kafka errorhandling by annotation,spring-boot,spring-kafka,Spring Boot,Spring Kafka,我尝试通过注释启用spring kafka错误处理 所以我创建了一个beankafkaListenerErrorHandler @Bean public KafkaListenerErrorHandler kafkaListenerErrorHandler(ErrorHandler errorHandler) { KafkaListenerErrorHandler kafkaListenerErrorHandler = (message, exception) -> {

我尝试通过注释启用spring kafka错误处理

所以我创建了一个bean
kafkaListenerErrorHandler

@Bean
public KafkaListenerErrorHandler kafkaListenerErrorHandler(ErrorHandler errorHandler) {
    KafkaListenerErrorHandler kafkaListenerErrorHandler = (message, exception) -> {
        MessageHeaders headers = message.getHeaders();
        ConsumerRecord<String, EventV1> consumerRecord = new ConsumerRecord<>(
                headers.get(KafkaHeaders.RECEIVED_TOPIC, String.class),
                headers.get(KafkaHeaders.RECEIVED_PARTITION_ID, Integer.class),
                headers.get(KafkaHeaders.OFFSET, Long.class),
                headers.get(KafkaHeaders.RECEIVED_MESSAGE_KEY, String.class),
                (EventV1) message.getPayload());
        errorHandler.handle(exception, Collections.singletonList(consumerRecord), headers.get(KafkaHeaders.CONSUMER, Consumer.class), messageListenerContainer);
        return null;
    };

    return kafkaListenerErrorHandler;
}
即使它看起来有效,代码看起来也很难看。
kafkaListenerErrorHandler
构造了一个新的ConsumerRecord,将其转发给ErrorHandler,“messageListenerContainer”为空,因为我不知道如何将其放入我的上下文中

应该或者必须有一种更优雅的方式来连接ErrorHandler和KafkaListenerErrorHandler

我还向设置中添加了反序列化错误处理程序

spring.kafka.consumer.value反序列化程序=org.springframework.kafka.support.serializer.ErrorHandlingDeserializer 2
spring.kafka.consumer.properties.spring.deserializer.value.delegate.class=org.springframework.kafka.support.serializer.JsonDeserializer
spring.kafka.consumer.properties.spring.json.trusted.packages=*

谢谢您的建议。

您不需要侦听器错误处理程序;spring boot将自动将
errorHandler
连接到侦听器容器中,如果侦听器抛出异常,将从那里调用它

此外,您所做的也是错误的,因为错误处理程序将只查找当前记录,并且在上一次轮询中可能会获取更多记录

KafkaListenerErrorHandler
s在堆栈中的位置较高,用于更高级的错误处理

例如,在请求/应答场景中,(侦听器方法返回应答值),侦听器错误处理程序可以向请求消息的发送者返回错误应答

编辑

例外情况可归类为“不可重试”

从版本2.3开始,
SeekToCurrentErrorHandler
认为某些异常是致命的,并跳过对这些异常的重试;在第一次失败时调用恢复程序。 默认情况下,被视为致命的例外情况包括:

  • 反序列化异常
  • MessageConversionException
  • MethodArgumentResolutionException
  • NoSuchMethodException
  • ClassCastException
因为这些异常不太可能在重试交付时得到解决

您可以向“不可检索”类别添加更多异常类型,或使用自己配置的分类器完全替换
BinaryExceptionClassifier
。 有关更多信息,请参阅
的Javadocs,请参阅ktocurInterrorHandler
,以及
spring retry
BinaryExceptionClassifier
的Javadocs

@Bean
public KafkaListenerErrorHandler kafkaListenerErrorHandler(ErrorHandler errorHandler) {
    KafkaListenerErrorHandler kafkaListenerErrorHandler = (message, exception) -> {
        MessageHeaders headers = message.getHeaders();
        ConsumerRecord<String, EventV1> consumerRecord = new ConsumerRecord<>(
                headers.get(KafkaHeaders.RECEIVED_TOPIC, String.class),
                headers.get(KafkaHeaders.RECEIVED_PARTITION_ID, Integer.class),
                headers.get(KafkaHeaders.OFFSET, Long.class),
                headers.get(KafkaHeaders.RECEIVED_MESSAGE_KEY, String.class),
                (EventV1) message.getPayload());
        errorHandler.handle(exception, Collections.singletonList(consumerRecord), headers.get(KafkaHeaders.CONSUMER, Consumer.class), messageListenerContainer);
        return null;
    };

    return kafkaListenerErrorHandler;
}
下面是一个将
IllegalArgumentException
添加到不可检索异常的示例:

@Bean

public SeektocurInterrorHandler错误处理程序(BiConsumerSo我可以删除这个连接代码,很好。但是我如何解决你提到的errorHandler查找问题呢?顺便说一下,我还添加了一个反序列化错误处理程序。比如spring.kafka.consumer.value反序列化器=org.springframework.kafka.support.serializer.ErrorHandlingDeserializer2 spring.kafka.consumer.properties.spring.deserializer.value.delegate.class=org.springframework.kafka.support.serializer.jsondesializer-spring.kafka.consumer.properties.spring.json.trusted.packages=*查找问题这只是因为您错误地从侦听器错误处理程序调用了错误处理程序。删除侦听器错误处理程序,它将正常工作。
ErrorHandlingDeserializer2
是一种机制,可以将反序列化异常发送到错误处理程序;没有它,Spring无法获得有关错误处理程序的足够信息问题。您好,还有一个问题。是否可以绕过重试并将特定异常直接转发到DLT?我看到您是新来的-欢迎使用堆栈溢出。不要在评论中询问更多问题;这不会帮助人们找到问题/答案;改为以新问题的形式提问。另外,请参阅接受答案使人们更容易找到问题/答案o找到好的答案。是的,您可以将某些异常分类为不可重试;请参阅“编辑我的答案”。