RetryTemplate与ErrorHandler的性能比较



我有两种方法可以使用从KafkaListener错误中恢复

  1. KafkaListener方法中的RetryTemplate:
@KafkaListener(topics: "topic1")
public void handle(command) {
retryTemplate.execute(ctx -> {
processCommand(command);
});
// Retries exhausted, execute the recoverer logic
recover(command);
}
  1. 通过ContainerCustomizer将ErrorHandler设置为MessageListenerContainer:
@Component
public class ContainerCustomizer {
public ContainerCustomizer(CustomConcurrentContainerListenerFactory factory) {
factory.setContainerCustomizer(container -> {
container.setErrorHandler(new SeekToCurrentErrorHandler((ConsumerRecord<?, ?> record, Exception e) -> {
//logic for recoverer after retries exhausted
recover(convertRecord(record));
}, new ExponentialBackOffWithMaxRetries(2)));
});
}
}

当谈到性能和阻塞使用者线程时,这两种选择的比较如何?使用RetryTemplate.execute,重试在一个单独的线程中处理,而使用containerListener.setErrorHandler,它会阻塞主要使用者的线程,这是真的吗?

两者都会阻塞使用者线程,否则您将继续处理记录,Kafka的订购保证将丢失。

此外,这两种方法都被弃用,取而代之的是DefaultErrorHandler,它是SeekToCurrentErrorHandler的演变。

两者之间的区别在于,使用Spring Retry,所有调用都将在内存中重试,因此您应该确保聚合回退不会超过max.poll.interval.ms,否则代理会认为您的服务器已经死了,并将执行重新平衡。

SeekToCurrentErrorHandlerDefaultErrorHandler将在每次重试时对代理执行新的查找,因此您只需要确保最大延迟加上执行时间不超过max.poll.interval.ms

如果您需要non-blocking retries,请查看非阻塞重试功能。

最新更新