Spring-Kafka:Consumer Group Rebalancing对Stateful Retry的影响

Spring-Kafka: Impact of Consumer Group Rebalancing on Stateful Retry

如果将 SeekToCurrentErrorHandler 与有状态重试一起使用,以便每次重试时从代理轮询消息,则存在这样的风险,即对于较长的重试期,消费者组重新平衡可能会导致分区重新分配给另一个消费者。因此,状态重试 period/attempts 将被重置,因为新消费者不知道重试的状态。

举个例子,如果重试的最长期限是 24 小时,但消费者组平均每 12 小时重新平衡一次,重试将永远无法完成,消息(以及消息背后的消息)最终会过期一旦他们超过了保留期,就从主题中删除。 (假设这次可重试异常的原因没有解决)。该消息不会像预期的那样在 24 小时后结束在 DLT 上,因为重试不会因重置而耗尽。

我假设即使消费者通过重新轮询消息来重试,也不能保证在重新平衡之后该消费者会保留对该分区的分配。或者我们是否可以确信,只要这个消费者实例还活着,它通常会保留对其正在轮询的分区的分配?

是否有最好的 practises/guidelines 使用有状态重试来满足此需求?

无状态重试意味着任何超过轮询超时的总重试时间都会导致重新平衡和重复消息传递。为避免这种情况,重试期必须非常有限。还是指导方针允许这样做,确保消费者对消息进行重复数据删除,以便可以接受重复的消息,并且可以配置长时间 运行 无状态重试?

使用重试主题是启用几个小时之类的重试期(例如,为了满足在此期间不可用的服务)的唯一安全和稳定的选择吗?

谢谢, 抢

有状态重试的全部意义在于避免重新平衡;没有它,消费者将被延迟到所有重试延迟的总和。

但是,侦听器适配器中的重试(包括有状态重试)现已弃用,因为错误处理程序现在可以执行 RetryTemplate 可以执行的所有操作(退避、异常分类等)。

使用有状态重试(或错误处理程序中的退避),最长退避必须小于 max.poll.interval.ms

坦率地说,24 小时的退避是荒谬的 - 最好停止容器并在一天后重新启动它。