Spring Kafka多个使用者针对单个主题消耗不同的消息

时间:2018-08-02 12:04:16

标签: java spring-boot apache-kafka spring-kafka

在我的Spring Boot Kafka应用程序中,我具有以下使用者配置:

@Bean
public ConsumerFactory<String, Post> postConsumerFactory(KafkaProperties kafkaProperties) {
    return new DefaultKafkaConsumerFactory<>(kafkaProperties.buildConsumerProperties(), new StringDeserializer(), new JsonDeserializer<>(Post.class));
}

@Bean
public ConcurrentKafkaListenerContainerFactory<String, Post> postKafkaListenerContainerFactory(KafkaProperties kafkaProperties) {

    kafkaProperties.getProperties().put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, kafkaConsumerMaxPollIntervalMs);
    kafkaProperties.getProperties().put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, kafkaConsumerMaxPollRecords);

    ConcurrentKafkaListenerContainerFactory<String, Post> factory = new ConcurrentKafkaListenerContainerFactory<>();
    factory.getContainerProperties().setAckMode(AckMode.MANUAL_IMMEDIATE);
    factory.setConsumerFactory(postConsumerFactory(kafkaProperties));

    return factory;
}

和消费者:

@KafkaListener(topics = "${kafka.topic.post.send}", containerFactory = "postKafkaListenerContainerFactory")
public void sendPost(ConsumerRecord<String, Post> consumerRecord, Acknowledgment ack) {

    // do some logic

    ack.acknowledge();
}

如果我理解正确,那么现在我只有一个消费者实例。我想增加邮政使用者的数量,假设有5个使用者将使用${kafka.topic.post.send}中的不同(不同)消息,以加快消息的使用。

例如,将factory.setConcurrency(5);添加到我的postKafkaListenerContainerFactory()就是这么简单吗?

@Bean
public ConcurrentKafkaListenerContainerFactory<String, Post> postKafkaListenerContainerFactory(KafkaProperties kafkaProperties) {

    kafkaProperties.getProperties().put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG, kafkaConsumerMaxPollIntervalMs);
    kafkaProperties.getProperties().put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, kafkaConsumerMaxPollRecords);

    ConcurrentKafkaListenerContainerFactory<String, Post> factory = new ConcurrentKafkaListenerContainerFactory<>();
    factory.getContainerProperties().setAckMode(AckMode.MANUAL_IMMEDIATE);
    factory.setConsumerFactory(postConsumerFactory(kafkaProperties));
    factory.setConcurrency(5);

    return factory;
}

还是我需要做一些额外的工作才能实现它?

1 个答案:

答案 0 :(得分:1)

这不是Apache Kafka的工作方式。一个想法总是在单个线程的同一分区中存在过程记录。 factory.setConcurrency(5);肯定与一个主题中有多少个分区有关。因此,如果只有一个,则此属性不会带来任何价值。如果您在主题中有10个分区,那么Spring Kafka会产生5个线程,并且每个线程将处理2个分区。

我想在Reference Manual中说得很清楚:

  

例如,如果提供了6个TopicPartition,并且并发为3;每个容器将获得2个分区。对于5个TopicPartition,两个容器将获得2个分区,第三个容器将得到1。如果并发大于TopicPartitions的数量,则并发性将向下调整,以使每个容器将获得一个分区。

因此,如果您希望具有这样的并发性,则实际上必须在主题中创建5个分区。而且只有在那之后,您才能并行处理同一主题中的记录。