Spring Kafka SeekToCurrentErrorHandler找出失败的记录

时间:2018-08-26 23:37:15

标签: apache-kafka spring-kafka spring-retry

我用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.commitfalse设置为auto.offset.reset

谢谢!

1 个答案:

答案 0 :(得分:3)

自春季以来,就有一个FailedRecordTracker用于Apache Kafka 2.2(尚未发布):

https://docs.spring.io/spring-kafka/docs/2.2.0.M2/reference/html/whats-new-part.html#_listener_container_changes

  

从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中的SeekToCurrentErrorHandlermaster源代码复制/粘贴到您的项目中,您将具有所需的功能:

https://github.com/spring-projects/spring-kafka/blob/master/spring-kafka/src/main/java/org/springframework/kafka/listener/SeekToCurrentErrorHandler.java

https://github.com/spring-projects/spring-kafka/blob/master/spring-kafka/src/main/java/org/springframework/kafka/listener/SeekToCurrentErrorHandler.java