一旦我收到来自kafka的消息,我需要运行一个长时间运行的进程(最多需要20秒),我只需要在此过程完成时将消息视为成功。
此外,我需要确保每条消息至少处理一次。
考虑使用具有以下属性的KafkaMessageListenerContainer:
listenerTaskExecutor的ThreadPoolTaskExecutor
使用AcknowledgingMessageListener类型的MessageListener
将确认模式设置为MANUL_IMMEDIATE。
但我唯一的问题是,如果首先成功处理具有偏移量15的特定消息,则会发生什么,但仍然正在处理带有14的消息。所以在这种情况下,我的偏移量将更新为15,即使14尚未处理
如何处理这类情况?
答案 0 :(得分:2)
你做不到;将提交更高的抵消。
如果您使用的是单个分区,则需要在同一个线程上处理每个请求或管理应用程序中的状态,以避免在出现间隙时提交偏移量。
这就是卡夫卡的工作方式。
更简单的解决方案是对数据进行分区;偏移由分区维护。使用change
,分区将分布在线程中;你不能在监听器中使用执行器。这样,容器可以在处理时为每个分区提交偏移量(ConcurrentMessageListenerContainer
)。
只需创建至少包含分区数量的主题即可满足您的并发要求 - 但通常最好对主题进行过度分区。
如果使用代理分区分配,则应确保将会话超时属性设置为安全地大于预期的最大20秒,以避免分区重新平衡。但是,只要您不使用自动提交,如果您的监听器耗时太长,容器将暂停使用者。