如何重试来自kafka的失败消息?

时间:2019-04-08 08:09:47

标签: spring-boot apache-kafka spring-kafka

我的spring-boot application(consumer)处理来自Apache Kafka的消息。定期地,按摩无法处理,并且消费者会抛出异常。消费者承诺无论如何都要抵消。  我可以在Kafka中区分成功消息与失败消息吗?我想,我做不到。是真的吗如果是真的,我的主要问题是:

如何重试失败消息?我知道一些方法,但是我不确定它们的正确性。

1)将偏移量更改为早期。但是通过这种方式,成功消息也会重试。

2)当我捕获到异常时,我将此消息发送到另一个主题(错误主题 例如)。但这看起来很困难。

3)其他(您的变体)

3 个答案:

答案 0 :(得分:3)

If you want at-least once guarantee, a general pattern is as follows:

  • Disable auto commit (set enable.auto.commit to false)
  • Consume messages
  • For each message:

    • If no errors, then commit offset
    • If error, retry as many times you wish
    • If successful, commit
    • If you want to give up, log or publish to an error queue (for analysis or later retry)
  • Repeat

答案 1 :(得分:0)

Use a SeekToCurrentErrorHandler. It will reposition the offset to replay the message (10 times by default, but configurable).

After the retries are exhausted, it calls a "recoverer" that can take some action, such as the DeadLetterPublishingRecoverer.

答案 2 :(得分:0)

您可以在 YourConsumer 配置中进行以下更改:

  1. enable.auto.commit=False

  2. RetryTemplate retryTemplate() {
        RetryTemplate retryTemplate = new RetryTemplate();
        FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
        fixedBackOffPolicy.setBackOffPeriod(retryInterval);
        retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
        retryTemplate.setRetryPolicy(new SimpleRetryPolicy(retryMaxCount));
    
        return retryTemplate;
    }
    
  3. 在您的 kafkaListenerContainerFactory 中:

    setretryTemplate(retryTemplate);
    factory.getContainerProperties().setAckOnError(true);
    factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.RECORD);
    

现在,在您的代码中,只要发生异常,就在您的使用者中抛出异常。这不会在发生异常时更新偏移量。并且它会在 retryInterval 时间后重试最多 maxRetryCount

如果您想忽略并且不重试某些类型的异常,请创建一个如下所示的异常映射并将其传递到 SimpleRetryPolicy() 中,如下面的代码所示:

Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<>();
        exceptionMap.put(IllegalArgumentException.class, false);
        exceptionMap.put(TimeoutException.class, true);

有关详细信息,请访问此链接:Kafka Error Handling