除了先前询问的有关交易的问题外,我还要询问有关控制消费的问题:我有一个监听器,用于处理生产数据。现在发生了一些不好的事情,并且由于任何原因,我们都希望启动我们的应用程序,但停止处理记录。因此,我希望可以选择手动(开始)停止使用者(我知道ContainerStoppingErrorHandler)。解决问题后,最终将它们重新定位并重新启动。
我认为我看到了一种解决方法,但是我希望有人可以向我确认这一点,因为可能有很多陷阱。整个过程似乎并不容易,而且我不确定自己是否做对了,也许还有更好的方法。
因此首先,为了能够暂停/停止使用者,我必须具有MessageListenerContainer的权限。意思是,我将在配置中创建:ConcurrentKafkaListenerContainerFactory,并且(从2.2开始)使用它来创建ConcurrentMessageListenerContainer的托管bean。然后可以使用此bean启动/停止使用者。作品。并且,一旦并发...我想,我传入setupMessageListener的对象必须是无状态类的实例,以便可以从多个线程/消费者对其进行操作。因此,如果我想像以前那样使用@KafkaListener注释方法在bean上进行弹簧依赖注入,则可以在此处传递无状态单例bean的实例。
现在要重新定位:这似乎很容易。只需在通过setupMessageListener和store回调注册的messageListener类中实现ConsumerSeekAware即可。然后,您可以仅自动联编ConsumerSeekAware messageListener单例并执行查找。相关的MessageListenerContainer,无论分区/并发设置如何,都应执行查找。因为当ConcurrentMessageListenerContainer以大于1的并发性启动时,它将在所有分区(?)上启动多个KafkaMessageListenerContainer a),但是由于所有共享相同的groupId,因此只有一个使用者将使用该消息,或者b)每个KafkaMessageListenerContainer将具有一些分区子集。但是在搜索中,我们必须指定topic + partition + offset,因此无论哪种情况,搜索都应由适当的KafkaMessageListenerContainer进行。
对吗?
我知道这令人生畏的文字/问题,但这也许对其他人也很有用。
答案 0 :(得分:0)
您不需要创建自己的容器
../../machines/name
然后,获取对machines
(自动接线等)的引用。
然后
@KafkaListener(id = "foo", topics = " ... "
或
KafkaListenerEndpointRegistry
停止所有registry.getListenerContainer("foo").stop();
。
当并发> 1时;您至少需要多个分区,否则某些使用者将处于空闲状态。
Kafka将分区分配给各个消费者;回调将被每个调用,并带有分配给它的分区列表。