目标:阅读主题中的所有消息,然后终止该过程。
我可以通过以下方式连续阅读消息:
props.put("bootstrap.servers", kafkaBootstrapSrv);
props.put("group.id", group_id);
props.put("max.poll.records", 1); // Only get one record at a time. I understand that to read all messages this will need to be increased
props.put("enable.auto.commit", "false");
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("MY_TOPIC"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(500);
for (ConsumerRecord<String, String> record : records) {
process_record(record);
}
consumer.commitSync();
}
但是在这种情况下,该过程永远不会终止。当我摆脱
while (true)
循环并运行该程序,它不会从该主题中获取一条记录(我希望有一条记录)。为什么会这样?
答案 0 :(得分:2)
Kafka主题基本上实现了无数事件。
那么从主题中消费时何时停止?你怎么知道你到达终点了? 简短的答案是你不知道!从理论上讲,制作人可以始终向该主题发送新消息。
实际上,假设没有附加新记录或只有很少新记录,您可以做一些事情来结束。
使用endOffsets()
可以找到分区的当前最后偏移量。使用者达到分配给它的所有分区的偏移量后,您可以停止轮询(或刷新它,并查看是否已发送新消息)。
您可以使用position()
方法来检索每个分区中的当前位置。在消耗时,每个记录还通过offset()
公开其自己的偏移量。因此,您可以使用它们来跟踪向终点偏移的进度。
关于您的第二个问题,poll()
首次调用时不返回任何内容。可以预期,因为基本上poll()
使客户端正常工作,并且在第一次调用时,它将启动与集群的连接并启动组协议(这需要几秒钟),因此不太可能在之前就已经收到消息poll()
返回。