Apache kafka Kafka 0.9无法使生产者和消费者API正常工作

Apache kafka Kafka 0.9无法使生产者和消费者API正常工作,apache-kafka,kafka-consumer-api,kafka-producer-api,Apache Kafka,Kafka Consumer Api,Kafka Producer Api,正在尝试新的0.9消费者API和生产者API。但似乎无法让它工作。我有一个生产者,在一个主题的两个分区中,每个分区产生100条消息。我的代码读起来像 Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); props.put("acks", "1"); props.put("retries", 0); props.put("batch.si

正在尝试新的0.9消费者API和生产者API。但似乎无法让它工作。我有一个生产者,在一个主题的两个分区中,每个分区产生100条消息。我的代码读起来像

    Properties props = new Properties();
    props.put("bootstrap.servers", "localhost:9092");
    props.put("acks", "1");
    props.put("retries", 0);
    props.put("batch.size", 2);
    props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
    props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

    Producer<String, String> producer = new KafkaProducer<>(props);
    System.out.println("Created producer");
    for (int i = 0; i < 100; i++) {
      for (int j = 0; j < 2; j++) {
        producer.send(new ProducerRecord<>("burrow_test_2", j, "M_"+ i + "_" + j + "_msg",
            "M_" + i + "_" + j + "_msg"));
        System.out.println("Sending msg " + i + " into partition " + j);
      }
      System.out.println("Sent 200 msgs");
    }

    System.out.println("Closing producer");
    producer.close();
    System.out.println("Closed producer");
Properties=newproperties();
put(“bootstrap.servers”,“localhost:9092”);
道具放置(“阿克斯”,“1”);
道具放置(“重试”,0);
道具放置(“批量大小”,2);
put(“key.serializer”、“org.apache.kafka.common.serialization.StringSerializer”);
put(“value.serializer”、“org.apache.kafka.common.serialization.StringSerializer”);
制作人=新卡夫卡制作人(道具);
System.out.println(“创建的生产者”);
对于(int i=0;i<100;i++){
对于(int j=0;j<2;j++){
生产商发送(新生产记录(“burrow_test_2”,j,“M_”+i+“+j+”),
“M”+i+“M”+j+“M”);
System.out.println(“将消息“+i+”发送到分区“+j”);
}
System.out.println(“发送200毫秒”);
}
System.out.println(“结案制作人”);
producer.close();
System.out.println(“封闭生产者”);
现在producer.close需要很长时间才能关闭,我假设所有缓冲区都会被刷新,消息会被写入日志尾部

现在我的消费者,我想在退出前阅读指定数量的消息。我选择在阅读时手动提交偏移量。代码读起来像

    int noOfMessagesToRead = Integer.parseInt(args[0]);
    String groupName = args[1];

    System.out.println("Reading " + noOfMessagesToRead + " for group " + groupName);
    Properties props = new Properties();
    props.put("bootstrap.servers", "localhost:9092");
    props.put("group.id", groupName);
    //props.put("enable.auto.commit", "true");
    //props.put("auto.commit.interval.ms", "1000");
    props.put("session.timeout.ms", "30000");
    props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
    KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
    consumer.subscribe(Arrays.asList("burrow_test_2"));
    //consumer.seekToEnd(new TopicPartition("burrow_test_2", 0), new TopicPartition("burrow_test_2", 1));
    int noOfMessagesRead = 0;
    while (noOfMessagesRead != noOfMessagesToRead) {
      System.out.println("Polling....");
      ConsumerRecords<String, String> records = consumer.poll(0);
      for (ConsumerRecord<String, String> record : records) {
        System.out.printf("offset = %d, key = %s, value = %s", record.offset(), record.key(),
            record.value());
        noOfMessagesRead++;
      }
      consumer.commitSync();
    }
  }
int noOfMessagesToRead=Integer.parseInt(args[0]);
字符串groupName=args[1];
System.out.println(“读取”+noOfMessagesToRead+”表示组“+groupName”);
Properties props=新属性();
put(“bootstrap.servers”,“localhost:9092”);
props.put(“group.id”,groupName);
//props.put(“enable.auto.commit”、“true”);
//props.put(“auto.commit.interval.ms”,“1000”);
props.put(“session.timeout.ms”,“30000”);
put(“key.deserializer”、“org.apache.kafka.common.serialization.StringDeserializer”);
put(“value.deserializer”、“org.apache.kafka.common.serialization.StringDeserializer”);
卡夫卡消费者=新卡夫卡消费者(道具);
consumer.subscribe(Arrays.asList(“burrow_test_2”));
//consumer.seekToEnd(新主题分区(“burrow_test_2”,0),新主题分区(“burrow_test_2”,1));
int noOfMessagesRead=0;
while(noOfMessagesRead!=noOfMessagesRead){
System.out.println(“轮询…”);
ConsumerRecords记录=consumer.poll(0);
对于(消费者记录:记录){
System.out.printf(“偏移量=%d,键=%s,值=%s”,record.offset(),record.key(),
record.value());
NoofMessageRead++;
}
consumer.commitSync();
}
}
但是,我的消费者总是停留在轮询调用上(即使我已将超时指定为0,也不会返回)

现在,为了确认,我尝试从Kafka
bin/Kafka-console-consumer.sh提供的命令行控制台consumer中消费--从一开始--新消费者--主题burrow_test_2--引导服务器localhost:9092

现在,这似乎是只读的,只使用在我启动java producer之前生成的消息

所以问题是

  • 上面的Java producer有什么问题
  • 为什么消费者没有轮询任何东西(我有一些旧消息,控制台消费者可以很好地读取它们)
  • 更新:我的坏消息。我启用了从本地主机到运行Kafka,ZK的远程机器的端口转发。在这种情况下,似乎存在一些问题。在localhost上运行似乎会生成消息


    我唯一剩下的问题是,使用消费者API,我无法
    查找
    偏移量。我尝试了
    seekToEnd
    seektoBegining
    两种方法,都抛出了一个异常,表示找不到记录。那么,消费者寻求补偿的方式是什么呢。
    auto.offset.reset
    consumer property是唯一的选项吗?

    您读过这篇文章吗?它解释了不同的偏移管理选项:谢谢您的回复。我认为,当偏移量存储在外部存储器中时,seek方法工作得很好。我能够使用道具放置(“自动偏移重置”、“最早”)并从已知的最早偏移量开始消费。您读过了吗?它解释了不同的偏移量管理选项:感谢您的回复。我认为,当偏移量存储在外部存储器中时,seek方法工作得很好。我能够使用道具放置(“自动偏移重置”、“最早”)并从已知的最早偏移量开始使用。