在1.3.5中停止ConcurrentMessageListenerContainer

时间:2018-07-01 03:30:07

标签: spring-kafka

我有一个问题要解决,还有更多要理解的问题,这样我才能正确地实施它。要求是通过在OOTB迭代KafkaMessageListenerContainer(基于定义的并发性)的容器上调用stop方法来停止ConcurrentMessageListenerContainer,并为每个使用者线程调用stop。

仅供参考,我在1.3.5上,由于Spring Boot 1.5,我无法迁移到2。*。

配置: 假设我有5个分区的主题,并发也定义为5。使用Batchlistener可以使每次轮询的批记录记录= 100。

问题: 当我们在容器上调用stop时,它在内部出现,它为每个KafkaMessageListenerContainer设置运行为false,并在listenerConsumer上调用唤醒。

Administrators

在测试我观察到的过程中,通过在单独的线程中调用容器上的stop,它执行以下操作:

1)它停止了listenerConsumer,这肯定可以正常工作。停止后,不再进行轮询。 2)似乎是否有任何listenerConsumer已经轮询了100条记录,并且在处理过程中它在停止之前完成了执行。 每个调用容器停止的设计仅发送唤醒第二个轮询以停止下一个轮询的每个设计?因为我在KafkaMessageListenerContainer.run()中看不到下面的任何处理

setRunning(false);
this.listenerConsumer.consumer.wakeup();

还有一件事情,即使是在春季kafka 2.1版本中,通过使用ContainerStoppingBatchErrorHandler,它也会调用相同的容器停止,所以我想我应该更多地了解如何处理这种情况。

总而言之,如果上面有更多细节,如果要从单独的线程中调用stop,我想终止listenerThread。我有手动偏移提交,因此可以重播批处理。

嗨,加里,

正如您建议使用消费者感知的侦听器一样,我的问题特定于通过容器停止侦听器。容器调用stop之后,侦听器线程应该被认为是BatchListner的执行中断。我知道监听器已收到整个记录轮询,而问题不是因为ack处于批处理级别而丢失偏移。

1 个答案:

答案 0 :(得分:0)

目前尚不清楚您的问题是什么;处理完批处理后,当侦听器返回时,容器停止。

如果要在记录级别管理偏移,请不要使用BatchMessageListener;而是使用记录级的MessageListener

对于前者,民意测验返回的整批记录被视为工作单位;是否提交整个批次的偏移量。

即使具有记录级别的侦听器,容器也不会停止,直到将当前的记录批次发送给侦听器为止;在这种情况下,您应该做什么取决于确认模式;使用手动工具,只需忽略停止后收到的那些记录。如果容器负责管理货架;为要丢弃的记录引发异常(使用ackOnError=false-默认为true)。

很遗憾,您不能升级到最新版本。

使用2.1;有更多的灵活性。例如;提供了SeekToCurrentErrorHandlerSeekToCurrentBatchErrorHandler

SeekToCurrentErrorHandler扩展了RemainingRecordsErrorHandler,这意味着轮询中的其余记录将发送到错误处理程序,而不是侦听器;当容器检测到RemainingRecordsErrorHandler时,侦听器将不会获得该批处理中的剩余记录,并且处理程序可以决定要执行的操作-停止容器,执行查找等。

因此,当收到不良记录时,您不再需要停止容器。

这都是为处理错误/由于某些数据错误而停止容器而设计的。

容器上目前没有stopNow()选项-处理完当前记录后立即停止调用侦听器,并丢弃所有剩余的记录,以便在开始时重新发送它们。目前,您必须如上所述将它们自己丢弃。

我们可以考虑添加这样的选项,但它最早是一个2.2功能。

我们仅在1.3.x中提供错误修复,然后,除非没有解决方法。

它是开源的,因此您随时可以自己创建它,并为框架做出贡献。