为什么我的简单Kafka Consumer示例不起作用

时间:2018-05-29 15:40:50

标签: apache-kafka kafka-consumer-api

我面临着让一个非常基本的卡夫卡消费者工作的问题。我正在使用kafka-clients-1.1.0.jar

以下是我所做的一切。

  1. 在命令行上启动zookeeper(所有命令都从中运行)
  2. zookeeper-server-start.bat ../../config/zookeeper.properties

    1. 启动Kafka服务器
    2. kafka-server-start.bat ../../config/server.properties

      1. 创建了一个新主题' hellotopic'并通过列出主题验证它
      2. kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic hellotopic Created topic "hellotopic".

        通过列出主题进行验证

        D:\RC\Softwares\kafka_2.12-1.1.0\kafka_2.12-1.1.0\bin\windows>kafka-topics.bat --list --zookeeper localhost:2181 hellotopic

        1. 在主题上发布消息并在控制台消费者身上验证相同
        2. kafka-console-producer.bat --broker-list localhost:9092 --topic hellotopic --property "parse.key=true" --property "key.separator=:"

          消息键和值输入如下

          key1:value1

          您可以在控制台消费者身上看到我们能够在主题' hellotopic'

          中看到该消息
          kafka-console-consumer.bat --zookeeper localhost:2181 --topic hellotopic --from-beginning
          

          上述命令的输出如下所示。我们可以看到消息值' value1'已发布

          Using the ConsoleConsumer with old consumer is deprecated and will be removed in a future major release. Consider using the new consumer by passing [bootstrap-server] instead of [zookeeper]. value1

          现在我们有一个带有消息的主题,我运行简单的Java kafka消费者代码来获取主题' hellotopic'中的所有消息。以下是代码

          import java.util.Arrays\;
          import java.util.Properties;
          import org.apache.kafka.clients.consumer.ConsumerRecord;
          import org.apache.kafka.clients.consumer.ConsumerRecords;
          import org.apache.kafka.clients.consumer.KafkaConsumer;
          public class SampleConsumer {
              public static void main(String[] args) {
                  System.out.println("Start consumer code");
                  Properties props = new Properties();
                   props.put("bootstrap.servers", "localhost:9092");
                   props.put("group.id", "test-consumer-group");
                   props.put("enable.auto.commit", "true");
                   props.put("auto.commit.interval.ms", "1000");
                   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("hellotopic"));
                   //while (true) {
                       ConsumerRecords<String, String> records = consumer.poll(100);
                       for (ConsumerRecord<String, String> record : records)
                           System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
                   //}
                   System.out.println("End consumer code");
              }
          }
          

          当我们运行上面的类时,这里是输出

          Start consumer code
          End consumer code
          

          尝试了很多问题,但没有运气。非常感谢这个简单例子的帮助。

1 个答案:

答案 0 :(得分:1)

我发现代码有两个问题:

  1. 您缺少使消费者从最早的偏移开始的特定配置:props.put("auto.offset.reset", "earliest"); 命令行使用者中的--from-beginning实际上已转换为此配置。如果没有为组中的相应主题和分区找到提交的偏移量,则此配置会告知使用者从最早的偏移量开始。
  2. 实际的poll应该在一个循环中。一个poll可能无法为消费者提供足够的时间来进行订阅并获取数据。进行民意调查的一种常见方式是:

    try {
        while (true) {
            ConsumerRecords<String, String> records = consumer.poll(100);
            for (ConsumerRecord<String, String> record : records)
                System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
        }
    } finally {
        consumer.close();
    }