我尝试使用相同的@KafkaListener实现从Kafka使用多个主题,但我希望每个主题都有一个使用者(每个主题只有一个分区)。为了实现这一点,我创建了@KafkaListener
topicPattern="topic1|topic2|topic3"
和ConcurrentKafkaListenerContainerFactory并发3和groupId consumer_group
。问题是所有主题都分配给同一个消费者,而其他2个消费者变为空闲,如下面的日志所示:
21:49:13.140 [org.springframework.kafka.KafkaListenerEndpointContainer#0-1-C-1] INFO o.a.k.c.c.i.ConsumerCoordinator - Setting newly assigned partitions [] for group consumer_group
21:49:13.140 [org.springframework.kafka.KafkaListenerEndpointContainer#0-2-C-1] INFO o.a.k.c.c.i.ConsumerCoordinator - Setting newly assigned partitions [] for group consumer_group
21:49:13.141 [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] INFO o.a.k.c.c.i.ConsumerCoordinator - Setting newly assigned partitions [topic1, topic2, topic3] for group consumer_group
我如何暗示Spring Kafka将每个主题传播给不同的消费者?
干杯
答案 0 :(得分:1)
为每个消费者使用不同的GroupID。由于您的所有3个消费者都在同一个群组中,因此他们会在主题之间划分分区。由于每个主题都有1个分区,因此只有一个消费者可以分配它。
同样不要在订阅调用中包含每个主题,只包括每个消费者所需的主题。
在KAFKAs网站上阅读更多内容。他们非常清楚地说明了这一点。
替代方法:保持相同的组ID,但让每个消费者都属于他们想要的主题
答案 1 :(得分:0)
并发消息侦听器容器将创建具有相同组ID的3个消费者;这是设计的。要做你想做的事,你需要3x @KafkaListener
,每个主题一个;当然,他们可以委托相同的方法。
@KafkaListener(topic = ...)
public void l1(...) {
doListen(...);
}
@KafkaListener(topic = ...)
public void l2(...) {
doListen(...);
}
@KafkaListener(topic = ...)
public void l3(...) {
doListen(...);
}
private void doListen(...) {
...
}
答案 2 :(得分:0)
尝试将分区分配策略更改为循环(或粘性)。因为你使用的是弹簧:
props.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG, RoundRobinAssignor.class.getName());