从多个Kafka主题中同时阅读1条消息

时间:2017-10-31 20:20:55

标签: java apache-kafka kafka-consumer-api spring-kafka

我将Kafka Listener的并发设置为1。

    ConcurrentKafkaListenerContainerFactory<String, Map<String, Object>> 
    factory = new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConcurrency(conncurrency);
    factory.setConsumerFactory(consumerFactory());
    factory.setRetryTemplate(retryTemplate());

我正在听3个不同的主题

    @KafkaListener(topics = "#{'${kafka.consumer.topic.name}'.split(',')}", containerFactory = "kafkaListenerContainerFactory")
    public void listen(@Payload Map<String, Object> conciseMap,
            @Header(KafkaHeaders.RECEIVED_PARTITION_ID) int partition,
            @Header(KafkaHeaders.OFFSET) int offset,
            Acknowledgment ack) {           
        processMessage(conciseMap,partition,offset,ack,false);
    }

在这种情况下,听众是否会从第一个主题&amp;处理后,从下一个主题读取1条消息,依此类推?或者它会同时处理来自每个主题的1条消息。

如果它是前者,有没有办法从所有主题同时读取1条消息而不创建多个监听器?

2 个答案:

答案 0 :(得分:1)

您不需要创建多个侦听器 - 您只需要在所有主题提供的分区中拥有尽可能大的并发性,甚至更多。

只会调整这样一定量的KafkaMessageListenerContainer,并且每个都将在自己的线程中工作。您仍然可以使用相同的@KafkaListener方法。只要你在那里没有无状态,你就没有任何并发​​问题。

答案 1 :(得分:1)

无法保证Kafka代理如何在容器线程中分配分区;如果你只有一个分区;它们可能都被分配到同一个容器线程中。这就是我用容器并发= 3 ...

运行测试时发生的事情
  

2017-10-31 16:40:26.066 INFO 35202 --- [ntainer#0-2-C-1] o.s.k.l.KafkaMessageListenerContainer:分配的分区:[]

     

2017-10-31 16:40:26.066 INFO 35202 --- [ntainer#0-1-C-1] o.s.k.l.KafkaMessageListenerContainer:分配的分区:[]

     

2017-10-31 16:40:26.079 INFO 35202 --- [ntainer#0-0-C-1] osklKafkaMessageListenerContainer:分配的分区:[bar-0,foo-0,baz-0]

每个主题有10个分区,我得到了这个分发......

  

2017-10-31 16:46:19.279 INFO 35900 --- [ntainer#0-1-C-1] osklKafkaMessageListenerContainer:分配的分区:[foo10-5,foo10-6,foo10-4,baz10- 5,baz10-4,baz10-6,bar10-5,bar10-4,bar10-6]

     

2017-10-31 16:46:19.279 INFO 35900 --- [ntainer#0-0-C-1] osklKafkaMessageListenerContainer:分配的分区:[bar10-1,bar10-0,bar10-3,bar10- 2,baz10-1,baz10-0,baz10-3,baz10-2,foo10-3,foo10-1,foo10-2,foo10-0]

     

2017-10-31 16:46:19.279 INFO 35900 --- [ntainer#0-2-C-1] osklKafkaMessageListenerContainer:分配的分区:[baz10-9,baz10-8,baz10-7,bar10- 9,bar10-8,foo10-9,bar10-7,foo10-7,foo10-8]

如您所见,每个主题的某些分区都分配给每个主题。但其中两个线程共有9个分区,而其中一个有12个。

如果你想要完全控制,我建议每个主题都有一个监听器。