我正在使用spring-kafka 2.2.8,并试图创建一个批处理使用者。这是我的问题。
假设我根据用户设置在每次轮询中接收到约100条记录,而这100条记录中只有一条记录由于某些下游系统错误而失败(这可能是暂时性错误,例如DB停机)几秒钟然后又回来等等),那么我想了解我是否可以为所有这100条记录提交偏移量,然后将失败的记录发送到其他主题或其他持久性存储中以便以后处理?
答案 0 :(得分:0)
从2.5版开始,现在有RecoveringBatchErrorHandler
;使用此错误处理程序,您将引发“特殊”异常以告诉错误处理程序批处理中的哪个记录失败。错误处理程序将提交先前的偏移量,然后重新查找失败的记录。
您可以添加退避时间,以将重新交付时间延迟一小会儿。重试用尽后,该记录将“恢复”(例如,通过发送到不公开信的主题)。
2.5版作为“重试批处理错误处理程序”的替代方法引入了RecoveringBatchErrorHandler。
这是批处理侦听器的默认错误处理程序。默认配置将重试9次(尝试10次传递),两次传递之间没有回退。
此错误处理程序与侦听器一起抛出一个BatchListenerFailedException一起工作,以提供发生故障的批次中的索引。如果侦听器引发其他异常,或者索引超出范围,则错误处理程序将退回到调用SeekToCurrentBatchErrorHandler并重试整个批处理,而无可用恢复。事件的顺序是:
在索引之前提交记录的偏移量。
如果重试未用尽,请执行搜索,以便重新发送所有剩余的记录(包括失败的记录)。
如果重试已用尽,请尝试恢复失败的记录(仅默认日志)并执行查找,以便重新传送其余记录(不包括失败的记录)。恢复的记录的偏移量已提交
如果重试已用尽而恢复失败,则执行查找,就好像重试未用尽。
重试用尽后,默认恢复程序将记录失败的记录。您可以使用自定义恢复程序,也可以使用框架提供的自定义恢复程序,例如DeadLetterPublishingRecoverer。
@Bean
public RecoveringBatchErrorHandler(KafkaTemplate<String, String> template) {
DeadLetterPublishingRecoverer recoverer =
new DeadLetterPublishingRecoverer(template);
RecoveringBatchErrorHandler errorHandler =
new RecoveringBatchErrorHandler(recoverer, new FixedBackOff(2L, 5000));
}
您可以提供失败的记录或其索引,但例外情况:
@KafkaListener(id = "recovering", topics = "someTopic")
public void listen(List<ConsumerRecord<String, String>> records) {
records.forEach(record -> {
try {
process(record);
}
catch (Exception e) {
throw new BatchListenerFailedException("Failed to process", record);
}
});
}