在spring-kafka中处理消费者错误后提交偏移

时间:2018-07-09 22:31:17

标签: apache-kafka kafka-consumer-api spring-kafka

我不完全了解消费者错误处理如何通过提交offset和akcMode以及如何通过在发生错误时停止容器来影响它(使用 spring-kafka 1.3。* )。

让我们说我有两个使用方(使用两个分区),它们在轮询(max.records.per.poll=5时都从其分区中获取5个事件。

第一个使用者-处理第一个事件好,处理第二个事件失败-因此在错误处理程序中,我调用kafkaListenerEndpointRegistry.stop(),但是由于实施了stop,它只是停止了使用者轮询,所以两个使用者仍然完成了其当前处理。批次。因此,第一个使用者处理事件3,4,5(所有事件均已处理且没有错误),并且可以说第二个使用者在第4个事件上失败(事件1,2,3,5被处理正常)。 我的问题是每个消费者将承担哪些补偿?

我的理解是:

  • 当我将AckMode.RECORD/BATCHackOnError结合使用时- 两个消费者都将获得最新的抵销额(5)
  • 当我将AckMode.RECORD/BATCH!ackOnError结合使用时-两个使用者都将提交最新的偏移量-因为尽管在批处理过程中某些事件失败,但批处理中的最新处理事件是可以的,所以最新处理后的事件抵消额获胜。

我的理解正确吗?

1 个答案:

答案 0 :(得分:3)

您的理解是正确的;当您停止容器时,还应该向侦听器发出信号,告知它也需要拒绝任何剩余的记录,这样就不会提交其偏移量。

我们正在考虑添加一种stopNow()方法,这将防止其他记录发送到侦听器。

在2.0中,我们添加了RemainingRecordsErrorHandler(和实现SeekToCurrentErrorHandler)。当容器检测到这样的错误处理程序时,它将其余记录呈现给错误处理程序而不是侦听器。

SeekToCurrentErrorHandler将所有主题/分区都查找到未处理的偏移量(包括失败的记录),以便在下一次民意测验中全部检索到它们。

自定义实现可能会查找剩余的记录,但会将失败的记录发送到死信主题(或以其他方式处理)。

也就是说,stopNow()对于大多数人来说可能更容易处理,但是可能仅是2.2功能; 1.3.x用户需要在失败后丢弃/拒绝未处理的记录。

您还可以使用RetryingMessageListenerAdapter(如果使用@KafkaListener则启用重试),这将根据重试配置重试交付,而完全不涉及Kafka。重试用尽并提交偏移量后,可以通过RecoveryCallback处理失败的记录;在这种情况下,无需停止容器。