簡體   English   中英

如何在程序中停止 Python Kafka Consumer?

[英]How to stop Python Kafka Consumer in program?

我正在做 Python Kafka 消費者(嘗試在http://kafka-python.readthedocs.org/en/latest/apidoc/kafka.consumer.html 中使用 kafka.consumer.SimpleConsumer 或 kafka.consumer.simple.SimpleConsumer )。 當我運行以下代碼時,它會一直運行,即使所有消息都被消耗了。 我希望消費者在消費完所有消息后會停止。 怎么做? 我也不知道如何使用 stop() 函數(它在基類 kafka.consumer.base.Consumer 中)。

更新

我使用信號處理程序來調用consumer.stop()。 一些錯誤信息被打印到屏幕上。 但是程序仍然卡在 for 循環中。 當新消息進來時,消費者消費它們並打印它們。 我也試過 client.close()。 但同樣的結果。

我需要一些方法來優雅地停止 for 循環。

        client = KafkaClient("localhost:9092")
        consumer = SimpleConsumer(client, "test-group", "test")

        consumer.seek(0, 2)# (0,2) and (0,0)

        for message in consumer:
            print "Offset:", message.offset
            print "Value:", message.message.value

歡迎任何幫助。 謝謝。

我們可以首先檢查主題中最后一條消息的偏移量。 然后,在達到該偏移量時停止循環。

    client = "localhost:9092"
    consumer = KafkaConsumer(client)
    topic = 'test'
    tp = TopicPartition(topic,0)
    #register to the topic
    consumer.assign([tp])

    # obtain the last offset value
    consumer.seek_to_end(tp)
    lastOffset = consumer.position(tp)

    consumer.seek_to_beginning(tp)        

    for message in consumer:
        print "Offset:", message.offset
        print "Value:", message.message.value
        if message.offset == lastOffset - 1:
            break

使用iter_timeout參數設置等待時間。 如果將其設置為10,就像下面的代碼一樣,如果在10秒內沒有新消息出現,它將退出。 默認值為“無”,這意味着即使沒有新消息進入,使用者也將在此處阻止。

        self.consumer = SimpleConsumer(self.client, "test-group", "test",
                iter_timeout=10)

更新資料

以上不是一個好的方法。 當有大量消息進入時,很難設置足夠小的iter_timeout以保證停止。 因此,現在,我正在使用get_message()函數,該函數嘗試消耗一條消息並停止。 沒有新消息時不返回任何內容。

與Mohit的答案類似的解決方案,但使用了end_offsets函數。

from kafka import KafkaConsumer, TopicPartition

# settings
client = "localhost:9092"
topic = 'test'

# prepare consumer
tp = TopicPartition(topic,0)
consumer = KafkaConsumer(client)
consumer.assign([tp])
consumer.seek_to_beginning(tp)  

# obtain the last offset value
lastOffset = consumer.end_offsets([tp])[tp]

for message in consumer:
    print "Offset:", message.offset
    print "Value:", message.message.value
    if message.offset == lastOffset - 1:
        break

更簡單的解決方案:

改用poll()poll_timeout_ms poll()是非阻塞調用。

  • 在 while 循環之外創建一個計數器變量。
  • 每次 poll() 從 Kafka Brokers 獲取 0 條記錄時增加計數器。
  • 如果poll()提取記錄,則將計數器重置為 0
  • 如果 counter == 某個閾值(比如 10),則跳出循環並關閉使用者。

在這個邏輯中,我們依賴於這樣一個事實:如果poll()在 10 次后續調用中沒有獲取任何記錄,這意味着我們已經讀取了所有數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM