我用KafkaHandler
实现了一个Kafka使用者。我的使用者应该使用事件,然后针对每个事件向其他服务发送REST请求。我只想在该REST服务关闭时重试。否则,我可以忽略失败的事件。
我的容器工厂的配置如下:
@Bean
public ConcurrentKafkaListenerContainerFactory<String, MyCustomEvent>
kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, MyCustomEvent> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
factory.setStatefulRetry(true);
factory.setRetryTemplate(retryTemplate());
factory.setConcurrency(3);
ContainerProperties containerProperties = factory.getContainerProperties();
containerProperties.setAckOnError(false);
containerProperties.setAckMode(AckMode.RECORD);
containerProperties.setErrorHandler(new SeekToCurrentErrorHandler());
return factory;
}
我正在使用ExceptionClassifierRetryPolicy
设置例外和相应的重试策略。
重试一切看起来都不错。当我收到ConnectException
时它会重试,而当我收到IllegalArgumentException
时它会忽略。
但是,在IllegalArgumentException
情况下,SeekToCurrentErrorHandler
返回到未处理的偏移量(因为它向后搜索包括失败的消息的未处理的消息),最终导致立即重试失败的消息。消费者不断来回回访,重试百万次。
如果我有机会了解在SeekToCurrentErrorHandler
中哪个记录失败了,那么我将创建一个SeekToCurrentErrorHandler
的自定义实现,以检查失败的消息是否可重试(通过使用{{ 1}}字段)。如果它不可重试,那么我将其从thrownException
列表中删除以进行查找。
关于如何实现此功能的任何想法?
注意:records
设置为enable.auto.commit
,false
设置为auto.offset.reset
。
谢谢!
答案 0 :(得分:3)
自春季以来,就有一个FailedRecordTracker
用于Apache Kafka 2.2
(尚未发布):
从2.2版开始,
SeekToCurrentErrorHandler
现在可以恢复(跳过)一直失败的记录。默认情况下,失败10次后,将记录失败的记录(ERROR)。您可以使用自定义恢复程序(BiConsumer
)和/或最大失败次数来配置处理程序。
SeekToCurrentErrorHandler errorHandler =
new SeekToCurrentErrorHandler((record, exception) -> {
// recover after 3 failures - e.g. send to a dead-letter topic
}, 3);
因此,您需要的只是将FailedRecordTracker
中的SeekToCurrentErrorHandler
和master
源代码复制/粘贴到您的项目中,您将具有所需的功能:>