[英]Retry kafka Message Consumption On Database Failure
我对Kafka比较陌生。
我们处理来自kafka的消息并将其持久保存到数据库中。如果将它们持久保存到数据库中失败,则不会提交该消息。
我的问题是: 我们想知道如何重新使用未提交的消息?
我尝试了几种方法。
在这种情况下,最佳实践方法是什么? 提前致谢。
如果您使用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.