Kafka 0.9无法使Producer和Consumer API正常工作

时间:2016-05-25 10:00:01

标签: apache-kafka kafka-consumer-api kafka-producer-api

尝试新的0.9 Consumer API和Producer 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");

现在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();
    }
  }

但是我的消费者总是停留在轮询调用上(即使我已将超时指定为0,也永远不会返回)。

现在只是为了确认,我尝试使用Kafka bin/kafka-console-consumer.sh --from-beginning --new-consumer --topic burrow_test_2 --bootstrap-server localhost:9092提供的命令行控制台消费者。

现在,这似乎只是为了消耗在我启动java生成器之前生成的消息。

所以问题是

  1. 上面是Java生产者的问题
  2. 为什么消费者不会轮询任何内容(我的控制台消费者正在阅读较旧的消息)。
  3. 更新:我的不好。我从localhost启用了端口转发到运行Kafka,ZK的远程机器。在这种情况下,似乎存在一些问题。在localhost上运行似乎产生了消息。

    我唯一剩下的问题是,使用消费者API,我无法seek偏移。我尝试了两种seekToEndseekToBeginning方法,两者都抛出异常,说没有找到记录。那么消费者寻求抵消的方式是什么呢? auto.offset.reset消费者财产是唯一的选择吗?

0 个答案:

没有答案