Kafka的ZookeeperConsumerConnector.createMessageStreams永远不会返回

时间:2014-04-23 21:52:08

标签: clojure apache-kafka clj-kafka

我试图从我的Kafka 0.8.1群集中检索数据。我已经创建了ZookeeperConsumerConnector的实例,然后尝试在其上调用createMessageStreams。然而,无论我做什么,似乎createMessageStreams只是挂起而永远不会回来,即使这是我对Kafka所做的唯一事情。

阅读邮件列表似乎有时可能会出现一些原因,但据我所知,我还没有完成任何这些事情。

此外,我指出我实际上是在使用clj-kafka在Clojure中执行此操作,但我怀疑clj-kafka不是问题因为即使我运行此代码也遇到问题:

(.createMessageStreams
  (clj-kafka.consumer.zk/consumer {"zookeeper.connect" "127.0.0.1:2181"
                                   "group.id" "my.consumer"
                                   "auto.offset.reset" "smallest"
                                   "auto.commit.enable" "false"})
  {"mytopic" (int 1)})

clj-kafka.consumer.zk/consumer只是使用Consumer.createJavaConsumerConnector来创建ZookeeperConsumerConnector而不做任何过于花哨的事情。

此外,肯定有消息在" mytopic"因为从命令行我可以运行以下内容并取回我已经发送给主题的所有内容:

% kafka-console-consumer.sh --zookeeper 127.0.0.1:2181 --topic mytopic --from-beginning

所以它也不是主题是空的。

此时感到难过。想法?

ETA:通过"挂起"我想我真正的意思是它似乎旋转了一个线程然后一直停留在它从未做任何事情。如果我从REPL运行这段代码,我可以通过点击control-c来解决它,然后我得到这个错误:

IllegalMonitorStateException   java.util.concurrent.locks.ReentrantLock$Sync.tryRelease (ReentrantLock.java:155)

1 个答案:

答案 0 :(得分:1)

在中断REPL时,我遇到了同样的问题。它挂起的原因是由于consumer.zk命名空间中的lazy-iterate函数。从中读取消息的队列是LinkedBlockingQueue,并且对lazy-iterate函数的.hasNext调用在此队列上调用.take。这会在队列上创建一个读锁定,并将阻塞并等待,直到某些内容可用于取消队列。这意味着lazy-iterate函数永远不会实际返回。 lazy-iterate由'消息调用'功能,如果你不做

之类的事情
(take 2 (messages "mytopic" some-consumer))

然后消息函数永远不会返回并无限期挂起。我认为这是clj-kafka中的一个错误(或设计缺陷)。为了说明这确实发生了什么,请尝试设置" consumer.timeout.ms" " 0"在您的消费者配置中。它将抛出TimeoutExpection并将控制权返回给REPL。

这进一步造成了“资源”问题。宏。宏采用绑定到消费者,关闭函数和正文;它调用正文然后关闭fn。如果在体内,你打电话给'消息',身体永远不会返回,因此永远不会调用关机功能。如果调用shutdown,则消息函数WOULD返回,因为shutdown在队列上放置一条消息,指示消费者清理其资源和线程以准备GC。此宏将应用程序置于一种状态,其中退出主循环的唯一方法是终止应用程序(或调用它的线程)本身。图书馆在为生产环境做好准备之前肯定还有很长的路要走。