Java 使用DeadLetterPublishingRecoverer和手动确认模式的Spring Kafka侦听器

Java 使用DeadLetterPublishingRecoverer和手动确认模式的Spring Kafka侦听器,java,spring,spring-kafka,Java,Spring,Spring Kafka,我很难理解如何解决这个问题,所以我在这里问这个问题,希望其他人已经面临同样的问题。 我们正在使用手动确认模式运行@KafkaListener,死信恢复程序的重试限制为3。 由于业务逻辑,在特定情况下(外部依赖),我们不确认消息并暂停消费5分钟,因此需要手动确认模式 此外,对于由于某种原因无法处理的消息,我们确实需要死信队列 现在,在手动确认模式下的问题是,当侦听器/使用者达到重试限制并将其移动到dl队列时,他没有确认消息 如果使用者服务将重新启动,他将尝试一次又一次地使用消息,并将它们移动到dl

我很难理解如何解决这个问题,所以我在这里问这个问题,希望其他人已经面临同样的问题。 我们正在使用手动确认模式运行@KafkaListener,死信恢复程序的重试限制为3。 由于业务逻辑,在特定情况下(外部依赖),我们不确认消息并暂停消费5分钟,因此需要手动确认模式

此外,对于由于某种原因无法处理的消息,我们确实需要死信队列

现在,在手动确认模式下的问题是,当侦听器/使用者达到重试限制并将其移动到dl队列时,他没有确认消息

如果使用者服务将重新启动,他将尝试一次又一次地使用消息,并将它们移动到dl队列

有没有办法解决这个问题


来自汉堡的感谢和问候

如果可能,我会尽量避免使用手动确认;可能通过增加
max.poll.interval.ms
来代替

如果使用
AckMode.MANUAL\u IMMEDIATE
,则可以安全地直接在错误处理程序中的
使用者上执行提交


如果
super.handle()
未引发异常,则子类化
seektocurinterrorHandler
并重写
handle()
,这意味着将超过重试次数,您可以提交
使用者上的偏移量

提交者可以在提供给ContainerListenerFactory的SeektocurInterrorHandler实例上设置为true

参考文件

public void setCommitRecovered(布尔commitRecovered)

设置为true以提交已恢复记录的偏移量。必须使用ContainerProperties.AckMode.MANUAL\u立即>配置容器。>提交是同步还是异步取决于容器的syncCommits属性


我们已经在使用AckMode.MANUAL\u。感谢您快速的回答和简单的解决方案,Gary!尊敬并衷心感谢您在所有卡夫卡主题上对社区的帮助!嗨,我也有同样的问题。你可以分享一些示例代码来说明你是如何解决这个问题的,因为我还没有真正理解这里提到的解决方案。我正在使用DeadLetterPublishingRecoverer以及SeektocurInterrorHandler和ackOnError(true)。这似乎与您上面提到的原始主题上的消息不一致。请告诉我建议是否类似@Override public void handle(Exception thrownException,List consumer,MessageListenerContainer container){super.handle(thrownException,records,consumer,container);consumer.commitAsync()是的,除了
super.handle(…)
应该处于try/catch中,当没有异常时,它会重新抛出异常(如果抛出),并通过
使用者提交偏移量(因为这意味着记录已发送到DLT)。确认模式必须为手动模式,才能立即工作。非常感谢Gary。非常感谢你在这里的帮助。还有一个问题。当我们只需要在super.handle(…)没有异常的情况下调用consumer.commitAsync(),即当项目已成功移动到DLT时,为什么要在super.handle(…)周围使用try/catch?我的要求是仅在成功处理或成功发布到DLT时才在源主题中提交。那么,没有try/catch的代码片段是否会像使用try/catch(rethrow)一样,只在没有异常时提交?可能我遗漏了什么?在我看来,这应该是认可的答案,因为如果有一个实际的配置,那么创建一个子类(就像认可的答案所建议的那样)似乎是不必要的。