Kafka:如果我可以简单地 "not acknowledgment.acknowledge" 使用 "acknowledgment.nack" 有什么意义

Kafka: what is the point of using "acknowledgment.nack" if I can simply "not acknowledgment.acknowledge"

注意 Kafka 的新功能旨在否定确认,现在由 Spring-Kafka 支持,根据 /spring-kafka/docs/2.4.4.RELEASE/

"... 从 2.3 版本开始,Acknowledgment 接口有两个额外的方法 nack(long sleep) 和 nack(int index, long sleep)。第一个与记录侦听器一起使用,第二个与批处理侦听器一起使用。为您的侦听器类型调用错误的方法将引发 IllegalStateException。

...

使用记录侦听器,当调用 nack() 时,将提交任何未决的偏移量,丢弃上次轮询的剩余记录,并在其分区上执行查找,以便重新传送失败的记录和未处理的记录在下一个民意调查()。 通过设置 sleep 参数,可以在重新传递之前暂停消费者线程。当容器配置有 SeekToCurrentErrorHandler 时,这类似于抛出异常的功能。 “

好吧,如果消费者方面发生了一些错误,比如无法保存到数据库,假设消费者没有 acknowledgment.acknowledge(),据我所知,消息仍在轮询中并且它将再次 read/consumed。我想有人会说,使用 nack(..., some time) 消费者可以睡觉,让 read/consume 稍后再有机会,并且不会遇到错误。如果继续听这个话题不是问题,我的直接问题是:

使用 nack 而不是简单地不确认还有什么意义吗?

据我所知,消息将在池中保留的时间无论如何都比 nack sleep 长。因此,顺便说一句,如果消费者继续尝试获取消息并保存消息,那么假设问题在不到睡眠时间内得到解决,它将成功。

周围的点或优势是生产者以某种方式得到通知使用了nack。如果是这样,我可以在某些特定情况下找到一些价值。假设使用 Log Compation(只对最后一条消息状态感兴趣)或 Kafka 作为长期存储服务(我猜未来的版本将提供这个 - KIP 405

考虑到更一般的例外情况,我倾向于遵循

等方法

nack 只是使用 SeekToCurrentErrorHandler 的替代方法 - 它是在我们将 SeekToCurrentErrorHandler 设置为默认错误处理程序之前添加的(以前,默认值只是记录错误)。

STCEH 更复杂,您可以配置重试次数,配置重试次数耗尽后调用的恢复器(例如 DeadLetterPublishingRecoverer)。

nack不同于"not acknowledge";对于后者,如果您不抛出异常,您将从轮询中获得下一条记录(如果这是最后一条记录,则为下一条轮询);除非您使用 nack 或 STCEH 并抛出异常,否则您不会收到未确认记录的重新传送。