[英]kafka consumer to dynamically detect topics added
我正在使用 KafkaConsumer 來使用來自 Kafka 服務器(主題)的消息。
但問題是,如果主題是動態創建的(我的意思是在消費者代碼啟動之后),它將不起作用,但 API 說它將支持動態主題創建。這是供您參考的鏈接。
使用的 Kafka 版本:0.9.0.1
https://kafka.apache.org/090/javadoc/index.html?org/apache/kafka/clients/consumer/KafkaConsumer.html
這是JAVA代碼...
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "test");
props.put("enable.auto.commit", "false");
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);
Pattern r = Pattern.compile("siddu(\\d)*");
consumer.subscribe(r, new HandleRebalance());
try {
while(true) {
ConsumerRecords<String, String> records = consumer.poll(Long.MAX_VALUE);
for (TopicPartition partition : records.partitions()) {
List<ConsumerRecord<String, String>> partitionRecords = records.records(partition);
for (ConsumerRecord<String, String> record : partitionRecords) {
System.out.println(partition.partition() + ": " +record.offset() + ": " + record.value());
}
long lastOffset = partitionRecords.get(partitionRecords.size() - 1).offset();
consumer.commitSync(Collections.singletonMap(partition, new OffsetAndMetadata(lastOffset + 1)));
}
}
} finally {
consumer.close();
}
注意:我的主題名稱與正則表達式匹配。如果我重新啟動消費者,那么它將開始閱讀推送到主題的消息......
任何幫助都非常感謝...
在 apache kafka 郵件檔案中有一個答案。 我在下面復制它:
消費者支持配置選項“metadata.max.age.ms”,它基本上控制獲取主題元數據的頻率。 默認情況下,此設置相當高(5 分鍾),這意味着最多需要 5 分鍾來發現與您的正則表達式匹配的新主題。 您可以將其設置得較低以更快地發現主題。
所以在你的道具中你可以:
props.put("metadata.max.age.ms", 5000);
這將使您的消費者每 5 秒發現一次新主題。
您可以連接到 Zookeeper。 查看示例代碼。 實質上,您將在 Zookeeper 節點/brokers/topics
上創建一個觀察者。 當在這里添加新的孩子時,這是一個正在添加的新主題,您的觀察者將被觸發。
請注意,這個和另一個答案之間的區別在於,這個是一個觸發器,另一個是輪詢 - 這個將盡可能接近實時,另一個將在您的輪詢間隔內.
這是使用 KafkaConsumer api 為我工作的解決方案。 這是它的Java代碼。
private static Consumer<Long, String> createConsumer(String topic) {
final Properties props = new Properties();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
BOOTSTRAP_SERVERS);
props.put(ConsumerConfig.GROUP_ID_CONFIG,
"KafkaExampleConsumer");
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,
StringDeserializer.class.getName());
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,
StringDeserializer.class.getName());
// Create the consumer using props.
final Consumer<Long, String> consumer =
new KafkaConsumer<>(props);
// Subscribe to the topic.
consumer.subscribe(Collections.singletonList(topic));
return consumer;
}
public static void runConsumer(String topic) throws InterruptedException {
final Consumer<Long, String> consumer = createConsumer(topic);
ConsumerRecords<Long, String> records = consumer.poll(100);
for (ConsumerRecord<Long, String> record : records)
System.out.printf("hiiiii offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
consumer.commitAsync();
consumer.close();
//System.out.println("DONE");
}
使用它,我們可以使用來自動態創建的主題的消息。
使用 KafkaConsumer 類中的 subscribe 方法,該方法將模式作為主題列表的參數以從中獲取數據
/**
- 訂閱與指定模式匹配的所有主題以獲取動態分配的分區。 * 模式匹配將針對檢查時存在的所有主題定期進行。 * 這可以通過 {@code metadata.max.age.ms} 配置進行控制:通過降低 * 元數據的最大年齡,消費者將更頻繁地刷新元數據並檢查匹配的主題。 *
* 請參閱 {@link #subscribe(Collection, ConsumerRebalanceListener)} 了解有關 * 使用 {@link ConsumerRebalanceListener} 的詳細信息。 通常,當與提供的模式匹配的主題發生更改以及消費者組成員資格發生更改時,會觸發重新平衡。 * 組再平衡僅發生在對 {@link #poll(Duration)} 的主動調用期間。 * * @param 模式訂閱模式 * @param listener 非空監聽器實例,用於獲取分區分配/撤銷的通知 *
訂閱的主題 * @throws IllegalArgumentException 如果模式或偵聽器為空 * @throws IllegalStateException 如果 {@code subscribe()} 之前使用主題調用過,或者之前調用了 assign (沒有后續調用 {@link #unsubscribe()} ),或者如果沒有 * 配置至少一個分區分配策略 */ @Override public void
subscribe(Pattern pattern, ConsumerRebalanceListener listener) {
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.