Java 用@KafkaListener注释的方法未传播遇到的异常。由于此原因,无法调用我的重试配置

Java 用@KafkaListener注释的方法未传播遇到的异常。由于此原因,无法调用我的重试配置,java,spring-boot,apache-kafka,spring-kafka,spring-retry,Java,Spring Boot,Apache Kafka,Spring Kafka,Spring Retry,我有一个用@kafkaListener注释的Kafka侦听器方法。它接受Message类型的参数和确认。我处理收到的消息,并使用acknowledge.acknowledge()进行手动提交。我已在容器上设置了重试模板。重试策略定义为特定于异常的。为此,我创建了自己的RetryPlocity类,并使用ExceptionClassifierRetryPolicy进行了扩展。在该类中,根据收到的异常,我返回AlwaysRetryPolicy、NeverRetryPolicy和SimpleRetryP

我有一个用@kafkaListener注释的Kafka侦听器方法。它接受Message类型的参数和确认。我处理收到的消息,并使用acknowledge.acknowledge()进行手动提交。我已在容器上设置了重试模板。重试策略定义为特定于异常的。为此,我创建了自己的RetryPlocity类,并使用ExceptionClassifierRetryPolicy进行了扩展。在该类中,根据收到的异常,我返回AlwaysRetryPolicy、NeverRetryPolicy和SimpleRetryPolicy。我遇到的问题是,当在侦听器方法中处理消息的过程中发生DataAccessException时,我希望永远重试,并且我已经相应地配置了重试策略,但是listener方法总是抛出ListenerExecutionFailedException,而不是遇到的异常,该异常是在堆栈下面抛出的,直到listener方法从上面的消息处理方法中退出。由于此异常是由侦听器引发的,因此我的重试配置无法按预期工作

示例代码如下:

    @KafkaListener(topics = "topicName", containerFactory = "kafkaListenerContainerFactory")
    public void listenToKafkaTopic(@Payload Message<SomeAvroType> message, Acknowledgement ack){
      SomeAvroType type = message.getPayLoad();
      type.processIncomingMessage();
      ack.acknowledge();
   }
当我在调试模式下运行它,并在processIncomingMessage()中抛出TransientDataAccessException时,我希望总是重试,但侦听器方法不会抛出传播的异常,而是抛出ListenerExecutionFailedException,其原因(例如getCause())是TransientDataAccessException。因此重试策略的计算结果始终为NeverRetryPolicy。侦听器中是否有方法抛出传播的异常,以便正确执行重试配置?

请参阅及其
遍历使用属性

/**
 * Create a binary exception classifier.
 * @param defaultValue the default value to use
 * @param typeMap the map of types to classify
 * @param traverseCauses if true, throwable's causes will be inspected to find
 * non-default class
 */
public BinaryExceptionClassifier(Map<Class<? extends Throwable>, Boolean> typeMap, boolean defaultValue,
        boolean traverseCauses) {
    super(typeMap, defaultValue);
    this.traverseCauses = traverseCauses;
}
/**
*创建一个二进制异常分类器。
*@param defaultValue要使用的默认值
*@param typeMap要分类的类型的映射
*@param traversecaus如果为true,将检查throwable的原因以查找
*非默认类
*/
public BinaryExceptionClassifier(映射请参见及其
TraverseCaues
属性

/**
 * Create a binary exception classifier.
 * @param defaultValue the default value to use
 * @param typeMap the map of types to classify
 * @param traverseCauses if true, throwable's causes will be inspected to find
 * non-default class
 */
public BinaryExceptionClassifier(Map<Class<? extends Throwable>, Boolean> typeMap, boolean defaultValue,
        boolean traverseCauses) {
    super(typeMap, defaultValue);
    this.traverseCauses = traverseCauses;
}
/**
*创建一个二进制异常分类器。
*@param defaultValue要使用的默认值
*@param typeMap要分类的类型的映射
*@param traversecaus如果为true,将检查throwable的原因以查找
*非默认类
*/

公共二进制例外分类程序(MapI已经看到了这一点。一个简单的重试策略有一个构造函数要传递到BinaryExceptionClassifier的实例中。但除此之外,我还必须传递尝试次数。是否有办法根据异常传递尝试次数。我知道这不是直接转发。如果有,我正在寻找一种方法或示例。@G)ary RussellNo,但您可以使用当前的技术,对
BinaryExceptionClassifier
进行子类化,并调用
super.classify()
来确定要返回哪个策略。或者,只需对
LEFE.cause()进行分类即可
相反。用户异常总是被封装在LEFE中。我不太了解子类化BinaryExceptionClassifier技术。我的理解是我将编写一个扩展BinaryExceptionClassifier的类。不清楚类的内容。比如要调用的构造函数以及如何返回相应的策略通过调用super.classify()进行编辑。任何伪代码都会非常有帮助或提供详细的说明。我搜索了一些示例,但没有找到任何示例。@Gary Russell目前作为一个解决方案,我正在调用getCause()MyRetryPolicy类中Throwable类型的classifiable上的方法。这将为我提供抛出的异常,该异常被包装在ListenerExecutionFailedException中。使用该异常并执行检查实例并返回相应的重试策略。请让我知道这是否是一个好的做法是的;这是最佳解决方案-我没有我没有注意到您需要3个不同的策略;子类化只支持2个策略。用户异常将始终是
LEFE.cause
。我已经看到了这一点。一个简单的重试策略有一个构造函数要在BinaryExceptionClassifier的实例中传递。但是除此之外,我还必须传递尝试次数。有什么方法可以传递吗根据异常情况,尝试次数为。我知道这不是直接转发。如果您有,我正在寻找方法或示例。@Gary RussellNo,但您可以使用当前的技术,对
BinaryExceptionClassifier
进行子类化,并调用
super.classify()
确定返回哪个策略。或者,只需对
LEFE.cause()进行分类
相反。用户异常总是被封装在LEFE中。我不太了解子类化BinaryExceptionClassifier技术。我的理解是我将编写一个扩展BinaryExceptionClassifier的类。不清楚类的内容。比如要调用的构造函数以及如何返回相应的策略通过调用super.classify()进行编辑。任何伪代码都会非常有帮助或提供详细的说明。我搜索了一些示例,但没有找到任何示例。@Gary Russell目前作为一个解决方案,我正在调用getCause()MyRetryPolicy类中Throwable类型的classifiable上的方法。这将为我提供抛出的异常,该异常被包装在ListenerExecutionFailedException中。使用该异常并执行检查实例并返回相应的重试策略。请让我知道这是否是一个好的做法是的;这是最佳解决方案-我没有t注意到您需要3个不同的策略;子类化只支持2个策略。用户例外总是
LEFE.cause
/**
 * Create a binary exception classifier.
 * @param defaultValue the default value to use
 * @param typeMap the map of types to classify
 * @param traverseCauses if true, throwable's causes will be inspected to find
 * non-default class
 */
public BinaryExceptionClassifier(Map<Class<? extends Throwable>, Boolean> typeMap, boolean defaultValue,
        boolean traverseCauses) {
    super(typeMap, defaultValue);
    this.traverseCauses = traverseCauses;
}