当我使用producer.flush()
时有效,但根据kafka confluent issue却表现不佳,但是如建议的那样,我使用producer.poll(0)
但对主题没有任何消息,是否需要任何配置或我这里缺少什么?
self.producer.produce(topic.value, data.encode('utf-8'), callback=self.delivery_report)
self.producer.poll(0) # -> doesn't work
self.producer.flush() # -> works
答案 0 :(得分:0)
问题是poll()
不能使生产者同步,只是调用事件并触发您注册的任何callback()
。
您在前一行中发送的消息最肯定仍在生产者缓冲区中,也就是说,它甚至没有从您的网卡中发出,因此代理人不认可它,而您已经回调了注册未触发。这些内部缓冲区由内部kafka线程清空,这些线程等待达到一定时间/大小,然后将消息发送给代理。 poll()
呼叫在那里做零工作(只要生产者以前没有发送任何消息),因为(最肯定的)消息没有到达kafka经纪人(它甚至没有从制作人的主机中消失)。
调用flush()
时,就是使生产者成为同步者:它将使客户端等待任何未完成的消息传递到代理。这就是为什么只有在调用flush()
之后才能产生结果的原因。
Edenhill 很好地解释了in this snippet。
答案 1 :(得分:0)
消息没有发送到kafka,因为没有时间执行此操作。您的应用提前终止。
这将起作用:
self.producer.produce(topic.value, data.encode('utf-8'), callback=self.delivery_report)
timer.sleep(1) -- sleep for one seconds.
self.producer.poll(0)
生产者有两个缓冲区。第一个发送缓冲区,第二个响应缓冲区(来自kafka的响应)。
方法produce(...)
-正在向发送缓冲区添加新消息。默认情况下,后台线程尝试尽快发送消息,但是仍然需要一些时间来执行此操作。
方法poll(0)
-正在检查响应缓冲区并正在执行回调方法。如果缓冲区为空,则什么也不会发生。
方法flush()
-正在检查两个缓冲区,直到所有消息都将被处理并且正在执行回调方法为止。退出应用程序之前,请使用此方法。
用法示例。
def send(topic,message,callback_report):
producer.produce(topic,message,callback=callback_report)
producer.pool(0) // execute callback for previous messages,
for msg in big_collection_of_messages:
send('blabla',msg,delivery_report)
producer.flush()
//END OF APPLICATION
注意。这种解释大大简化了。