繁体   English   中英

在数据库失败时重试kafka消息消耗

[英]Retry kafka Message Consumption On Database Failure

我对Kafka比较陌生。

我们处理来自kafka的消息并将其持久保存到数据库中。如果将它们持久保存到数据库中失败,则不会提交该消息。

我的问题是: 我们想知道如何重新使用未提交的消息?

我尝试了几种方法。

  1. 重新启动使用者。 它可以工作,但是需要重新启动。
  2. 捕获应用程序异常并跳过kafka提交。 将消息存储到RAM中,然后重试。

在这种情况下,最佳实践方法是什么? 提前致谢。

如果您使用spring-Kafka项目,则可以使用ContainerStoppingErrorHandler,它将停止错误的容器。 以下是示例KafkaListener方法,该方法将重试DataAccessException并在耗尽后将错误传递给下面的Config类中定义的错误处理程序

@KafkaListener(topics = ("${spring.kafka.consumer.topic}"), containerFactory = "kafkaManualAckListenerContainerFactory")
@Retryable(include = DataAccessException.class, backoff = @Backoff(delay = 20000, multiplier = 3))
public void onMessage(List<ConsumerRecord<String, String>> recordList,
                      Acknowledgment acknowledgment, Consumer<?, ?> consumer) throws DataAccessException {

    try {
        kafkaSinkController.saveToDb(recordList);
        acknowledgment.acknowledge();
        LOGGER.info("Message Saved  DB");
    } catch (Exception e) {
        LOGGER.error("Other than db exception ", e)
    }
}

配置bean

@Bean
KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>>
kafkaManualAckListenerContainerFactory() {
    ConcurrentKafkaListenerContainerFactory<String, String> factory =
            new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(new DefaultKafkaConsumerFactory<String, String>(consumerConfig));
    factory.setConcurrency(concurrentConsumerCount);
    factory.getContainerProperties().setAckMode(AckMode.MANUAL_IMMEDIATE);
    factory.getContainerProperties().setBatchErrorHandler(new ContainerStoppingBatchErrorHandler()); 
//It will stop container and thus consumer will stop listening
    factory.setBatchListener(true);
    return factory;
}

当您想开始重用消息时,可以使用KafkaListenerEndpointRegistry(以下示例方法)启动容器以获取刷新,一旦数据库可用,可以通过公开此方法的端点来以编程方式调用此方法。

@Autowired
KafkaListenerEndpointRegistry registry;

public void startContainer() {
    try {
        registry.start(); 
    } catch (Exception ex) {
        //Todo
    }
}

上面的示例依赖于所有弹簧组件,但是如果没有spring-kafka项目,则可以实现相同的目标。

捕获异常并将消息发布到另一个Kafka重试主题,该主题将由另一个使用者单独处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM