Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 可以使用单个弹簧';s KafkaConsumer侦听器侦听来自同一/一个分区的多条消息?_Java_Spring_Apache Kafka_Kafka Consumer Api_Spring Kafka - Fatal编程技术网

Java 可以使用单个弹簧';s KafkaConsumer侦听器侦听来自同一/一个分区的多条消息?

Java 可以使用单个弹簧';s KafkaConsumer侦听器侦听来自同一/一个分区的多条消息?,java,spring,apache-kafka,kafka-consumer-api,spring-kafka,Java,Spring,Apache Kafka,Kafka Consumer Api,Spring Kafka,提供了一个具有n个分区的主题。 Spring的KafkaConsumer侦听器是否可以一次侦听来自同一个分区的多条消息 我通过设置setBatchListener(true)尝试了ConcurrentKafkListenerContainerFactory但消费者已开始使用来自不同分区的多条消息,而不是一条 public class BatchReceiverConfig { @Value("${kafka.bootstrap-servers}") private String

提供了一个具有n个分区的主题。 Spring的KafkaConsumer侦听器是否可以一次侦听来自同一个分区的多条消息

我通过设置
setBatchListener(true)尝试了
ConcurrentKafkListenerContainerFactory
但消费者已开始使用来自不同分区的多条消息,而不是一条

public class BatchReceiverConfig {

    @Value("${kafka.bootstrap-servers}")
    private String bootstrapServers;

    @Bean
    public Map<String, Object> consumerConfigs() {
        Map<String, Object> props = new HashMap<>();

        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.GROUP_ID_CONFIG, "batch4");
        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
        // maximum records per batch receive
        props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, "10");

        return props;
    }

    @Bean
    public ConsumerFactory<String, String> consumerFactory() {
        return new DefaultKafkaConsumerFactory<>(consumerConfigs());
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, String> factory =
                new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        factory.setConcurrency(2);
        // enable batch listeners
//        factory.setBatchListener(true);

        return factory;
    }

    @Bean
    public BatchReceiver receiver() {
        return new BatchReceiver();
    }
}


/* Listener */
@KafkaListener(id = "batch-listener", topics = TOPIC_TEST_BATCH)
    public void receive(List<String> data,
                        @Header(KafkaHeaders.RECEIVED_PARTITION_ID) List<Integer> partitions,
                        @Header(KafkaHeaders.OFFSET) List<Long> offsets) {

        LOGGER.info("start of batch receive");
        for (int i = 0; i < data.size(); i++) {
            LOGGER.info("received message='{}' with partition-offset='{}'", data.get(i),
                    partitions.get(i) + "-" + offsets.get(i));
            // handle message

            latch.countDown();
        }
        LOGGER.info("end of batch receive");
    }
公共类BatchReceiverConfig{
@值(${kafka.bootstrap servers}”)
私有字符串引导服务器;
@豆子
公共地图使用者配置(){
Map props=newhashmap();
put(ConsumerConfig.BOOTSTRAP\u server\u CONFIG,bootstrapserver);
put(ConsumerConfig.KEY\u反序列化程序\u类\u配置,StringDeserializer.CLASS);
put(ConsumerConfig.VALUE\u反序列化程序\u类\u配置,StringDeserializer.CLASS);
props.put(ConsumerConfig.GROUP_ID_CONFIG,“batch4”);
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,“最早”);
//每批接收的最大记录数
props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG,“10”);
返回道具;
}
@豆子
公共消费者工厂消费者工厂(){
返回新的DefaultKafkanConsumerFactory(consumerConfigs());
}
@豆子
公共ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory(){
ConcurrentKafkalistener集装箱工厂=
新的ConcurrentKafkaListenerContainerFactory();
setConsumerFactory(consumerFactory());
工厂设置并发(2);
//启用批处理侦听器
//factory.setBatchListener(true);
返回工厂;
}
@豆子
公用接收器(){
返回新的BatchReceiver();
}
}
/*听众*/
@KafkaListener(id=“批处理侦听器”,topics=TOPIC\u TEST\u batch)
公共无效接收(列表数据,
@标题(KafkaHeaders.RECEIVED_PARTITION_ID)列出分区,
@标题(KafkaHeaders.OFFSET)列表偏移量){
LOGGER.info(“批量接收开始”);
对于(int i=0;i
如果一个组中只有一个消费者,那么您可以将该
ConcurrentKafkaListener
并发级别设置为
n
如果您使用组管理,Kafka将为您的消费者分配分区。每个使用者(或使用并发时的线程)将获得0、1或更多分区,具体取决于使用者和分区的数量

如果您希望某个特定的使用者仅从一个分区获取消息,则必须自己分配分区,而不是让Kafka进行分配


如果您使用并发容器;您必须分配与并发相同数量的分区,这样每个线程只能获得一个分区。

重新表述您的问题:“单个侦听器如何只能使用一个分区的消息?”。这是正确的吗?这是正确的,但在spring kafka模块的上下文中。它不起作用,我相信“max.poll.records”是决定要获取的记录数的属性。演示如何配置spring kafka和kafka使用者本身。添加了有问题的片段本身。在有问题的片段中,#of partitions=并发性,即使这样它也不工作。另外,消费者的数量=分区的数量。如果您使用的是组管理,则分区的分发需要时间;最初,消费者将获得所有这些信息;唯一的保证是自己分配分区,而不是使用组管理<代码>props.put(ConsumerConfig.GROUP_ID_CONFIG,“batch4”)
在集群环境中,很难定义这一点,因为相同的代码部署到所有节点。有什么方法可以动态配置它吗?有一种方法可以延迟分区分配。我们正在努力为该客户添加支持。然而,即使这样,仍然不能保证——如果您的一个实例死亡,它的分区将被重新分配。唯一的保证是使用手动分配;您可以使用属性占位符;每个实例具有不同的属性。