【问题标题】:duplicate consumption of messages with Spring Cloud Stream Kafka binder使用 Spring Cloud Stream Kafka binder 重复消费消息
【发布时间】:2020-05-13 22:06:43
【问题描述】:

我们有几个使用 Spring Boot 和 Spring Cloud Stream Kafka binder 的微服务在它们之间进行通信。

有时,我们会观察到消费者收到大量重复消息 - 通常是在首次消费和处理(成功)之后的几天。

虽然我知道 Kafka 不保证只交付一次,但它看起来仍然很奇怪,因为无论是代理还是服务的日志中都没有重新平衡事件或任何“可疑”活动。由于消费者是在与外部 API 交互,所以要使其具有幂等性有点困难。

任何提示可能是重复的原因?我应该寻找什么来解决这个问题?

我们使用的是 Kafka 代理 1.0.0,而这个特定的消费者使用 Spring Cloud Stream Binder Kafka 2.0.0,它基于 kafka-client 1.0.2(其他服务的版本可能有点不同)。

【问题讨论】:

    标签: spring-boot apache-kafka spring-kafka spring-cloud-stream spring-cloud-stream-binder-kafka


    【解决方案1】:

    当你问这样的问题时,你应该展示你的配置。

    最好的猜测是经纪人的offsets.retention.minutes

    对于现代代理版本(自 2.0 起),默认为 1 周;旧版本只有一天。

    【讨论】:

    • 非常感谢,@gary-russell!事实上,这个参数没有设置,看起来偏移量正在被重置并且消息被重新消费。但是,消费者组正在运行,没有长时间的中断。知道会发生什么会导致经纪人触发清理吗?
    • 请参阅this answer 上的 looooong 讨论。事实证明,对于较旧的代理,offsets.retention.minutes 只是自上次提交以来的时间,即使消费者只是短暂停止(如果它在最后一天没有收到任何记录),也会重置偏移量。对于较新的代理,消费者必须离线才能删除offsets.retention.minutes。不知道什么时候改的(不过属性描述在2.1变了)
    • 其实比我想象的还要糟糕;使用 1.0 代理,即使消费者仍在运行,也会删除偏移量。因为position() 仍然保留,所以这不是一个真正的问题。但是,如果您有两个应用程序实例共享分区并且偏移量保留时间已过而没有提交,则偏移量将被删除。如果您随后关闭一个实例,则会发生重新平衡,并且所有记录都会在剩余的实例上重放。这对于当前的代理(使用 2.4.1 和 2.5 进行测试)来说不是问题,因为直到消费者停止了这么长时间,它们才会被删除。
    • 非常感谢!这真的很有帮助。我们一定会考虑升级到新版本的经纪人。同时,希望增加抵消保留期会有所帮助。
    猜你喜欢
    • 2018-03-09
    • 1970-01-01
    • 2018-06-20
    • 2022-01-22
    • 2023-01-03
    • 1970-01-01
    • 2023-03-29
    • 2016-06-21
    • 2017-06-22
    相关资源
    最近更新 更多