如何使Kafka使用者从特定主题分区Spring Boot读取

时间:2019-10-18 13:46:35

标签: java spring-boot apache-kafka

我是Kafka和Spring Boot的新手,正在尝试使我的应用程序从该主题的特定分区读取。

 @KafkaListener(id = "singleLnr", groupId = "${kafka.consumer.group.id}",containerFactory = "singleFactory", topicPartitions = @TopicPartition(topic = "${kafka.topic.singleAttendance}", partitions = {"0"}))
public void consume2(ConsumerRecord attendanceInfo) {
    System.out.println(attendanceInfo);
}

单个工厂代码

@Bean(name = "singleFactory")
public KafkaListenerContainerFactory singleFactory() {
    ConcurrentKafkaListenerContainerFactory<String, Map<String, String>> factory = new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(consumerFactory());
    factory.setBatchListener(false);
    factory.setMessageConverter(converter());
    return factory;
}

这也是我的消费者工厂配置

 @Bean(name = "consumerFactory")
public ConsumerFactory<String, Map<String, String>> consumerFactory() {
    Map<String, Object> props = new HashMap<>();
    props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaBootstrapAddress);
    props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true);
    props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, 1000);
    props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, 60000);
    props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    props.put(ConsumerConfig.GROUP_ID_CONFIG, kafkaConsumerGroupId);
    return new DefaultKafkaConsumerFactory<>(props);
}

当我尝试运行程序时,它给我一个错误

  

在偏移量308的分区single.attendance-0上,偏移提交失败:协调器不知道该成员。

和警告

  

失败:由于该组已经重新平衡并将分区分配给另一个成员,因此无法完成提交。这意味着后续调用poll()之间的时间比配置的max.poll.interval.ms更长,这通常意味着轮询循环在消息处理上花费了太多时间。您可以通过增加max.poll.interval.ms或通过使用max.poll.records减小poll()中返回的批处理的最大大小来解决此问题。

如何使我的使用者从特定分区读取?你能不能至少给个提示。

1 个答案:

答案 0 :(得分:0)

Kafka自己为每个分区分配使用者。在此实现中,无需在@KafkaListener中对其进行配置。

@KafkaListener(id = "singleLnr", groupId = "${kafka.consumer.group.id}",containerFactory = "singleFactory", topics = "${kafka.topic.singleAttendance}")
    public void consume2(ConsumerRecord attendanceInfo) {
        System.out.println(attendanceInfo);
    }