我开始使用Confluent Platform,这需要运行Zookeeper(zookeeper-server-start /etc/kafka/zookeeper.properties
),然后运行Kafka(kafka-server-start /etc/kafka/server.properties
)。我正在编写一个应该运行Kafka和Zookeeper的Upstart脚本。问题是Kafka应该阻止,直到Zookeeper准备好(因为它取决于它)但我找不到一个可靠的方法来知道Zookeeper何时准备就绪。以下是运行Zookeeper服务器启动后伪代码的一些尝试:
使用硬编码块
sleep 5
在较慢的计算机上无法可靠地工作和/或等待的时间超过了所需的时间。
检查什么时候(希望Zookeeper)在端口2181上运行
wait until $(echo stat | nc localhost ${port}) is not none
这似乎不起作用,因为它没有等待足够长的时间让Zookeeper接受Kafka连接。
检查日志
wait until specific string in zookeeper log is found
这是粗略的,甚至连字符串都不能在错误中找到(例如"绑定到端口[...]")。
有没有可靠的方法知道Zookeeper何时准备好接受Kafka连接?否则,我将不得不采用1和2的组合。
答案 0 :(得分:3)
评论中的Kafka错误消息绝对相关:
致命[Kafka Server 0],KafkaServer启动时发生致命错误。准备关闭(kafka.server.KafkaServer)java.lang.RuntimeException:代理已经在路径/ broker / ids / 0上注册。这可能表示您已配置已经在使用的brokerid,或者您已关闭此代理并以比zookeeper超时更快的速度重新启动它,因此它似乎正在重新注册。
这表明ZooKeeper已启动并正在运行,Kafka能够连接到它。正如我所料,技术#2足以验证ZooKeeper是否已准备好接受连接。
相反,问题似乎出现在卡夫卡方面。它注册了一个ZooKeeper ephemeral node来代表起始的Kafka经纪人。当客户端的ZooKeeper会话到期时,会自动删除一个临时节点(例如,该进程终止,因此它会停止对ZooKeeper的心跳)。但是,这是基于超时。如果Kafka代理快速重启,则在重新启动后,它会看到代表该代理的znode已经存在。对于新流程的开始,这看起来已经有一个经纪人在该路径上启动并注册。由于经纪人应该拥有唯一的ID,因此会中止。
等待ZooKeeper会话过期后的一段时间是对此问题的适当响应。如有必要,您可以将会话过期调整为更快,如ZooKeeper Administrator's Guide中所述。 (请参阅tickTime
,minSessionTimeout
和maxSessionTimeout
的讨论。)但是,将会话过期调整为过快的行为可能会导致客户端在正常操作期间遇到虚假的会话过期。
我对卡夫卡的了解较少,但也许在卡夫卡方面也可以做些什么。我知道像Apache Ambari这样的管理工具会采取措施保证在配置时为每个代理分配唯一的ID。
答案 1 :(得分:0)
3.3.0版中引入的Confluent CLI使用一个命令启动所有服务变得非常简单:
confluent start
中的更多详细信息
答案 2 :(得分:0)
我发现使用计时器不可靠。第二种选择(等待港口)对我有用:
bin/zookeeper-server-start.sh -daemon config/zookeeper.properties && \
while ! nc -z localhost 2181; do sleep 0.1; done && \
bin/kafka-server-start.sh -daemon config/server.properties