我能够在一台Linux机器上获得一个简单的单节点Kafka(kafka_2.11-0.8.2.1)本地工作,但是当我尝试远程运行一个生产者时,我得到了一些令人困惑的错误。< / p>
我正在关注http://kafka.apache.org/documentation.html#quickstart的快速入门指南。我停止了kafka流程并删除了所有的zookeeper&amp; / tmp中的karma文件。我在本地10.0.0.0/24网络NAT-ed上使用外部IP地址,所以我修改server.properties
告诉zookeeper如何广播我的外部地址,按照https://medium.com/@thedude_rog/running-kafka-in-a-hybrid-cloud-environment-17a8f3cfc284:
advertised.host.name=MY.EXTERNAL.IP
然后我就跑了:
$ bin/zookeeper-server-start.sh config/zookeeper.properties
--> ...
$ export KAFKA_HEAP_OPTS="-Xmx256M -Xms128M" # small test server!
$ bin/kafka-server-start.sh config/server.properties
--> ...
我为远程计算机上的生产者打开了防火墙,并创建了一个新主题并对其进行了验证:
$ bin/kafka-topics.sh --create --zookeeper MY.EXTERNAL.IP:2181 --replication-factor 1 --partitions 1 --topic test123
--> Created topic "test123".
$ bin/kafka-topics.sh --list --zookeeper MY.EXTERNAL.IP:2181
--> test123
然而,我远程运行的制作人给了我错误:
$ bin/kafka-console-producer.sh --broker-list MY.EXTERNAL.IP:9092 --topic test123
--> [2015-06-16 14:41:19,757] WARN Property topic is not valid (kafka.utils.VerifiableProperties)
My Test Message
--> [2015-06-16 14:42:43,347] WARN Error while fetching metadata [{TopicMetadata for topic test123 ->
对于主题[test123],没有主题test123的分区元数据,因为kafka.common.LeaderNotAvailableException}]:class kafka.common.LeaderNotAvailableException(kafka.producer.BrokerPartitionInfo) - &GT; (重复几次)
(我禁用整个防火墙以确保问题不存在。)
重复karma-startup中的stdout错误:[2015-06-16 20:42:42,768] INFO Closing socket connection to /MY.EXTERNAL.IP. (kafka.network.Processor)
controller.log多次给我这个:
java.nio.channels.ClosedChannelException
at kafka.network.BlockingChannel.send(BlockingChannel.scala:100)
at kafka.controller.RequestSendThread.liftedTree1$1(ControllerChannelManager.scala:132)
at kafka.controller.RequestSendThread.doWork(ControllerChannelManager.scala:131)
at kafka.utils.ShutdownableThread.run(ShutdownableThread.scala:60)
[2015-06-16 20:44:08,128] INFO [Controller-0-to-broker-0-send-thread], Controller 0 connected to id:0,host:MY.EXTERNAL.IP,port:9092 for sending state change requests (kafka.controller.RequestSendThread)
[2015-06-16 20:44:08,428] WARN [Controller-0-to-broker-0-send-thread], Controller 0 epoch 1 fails to send request Name:LeaderAndIsrRequest;Version:0;Controller:0;ControllerEpoch:1;CorrelationId:7;ClientId:id_0-host_null-port_9092;Leaders:id:0,host:MY.EXTERNAL.IP,port:9092;PartitionState:(test123,0) -> (LeaderAndIsrInfo:(Leader:0,ISR:0,LeaderEpoch:0,ControllerEpoch:1),ReplicationFactor:1),AllReplicas:0) to broker id:0,host:MY.EXTERNAL.IP,port:9092. Reconnecting to broker. (kafka.controller.RequestSendThread)
运行此似乎表明领导者在0:
$ ./bin/kafka-topics.sh --zookeeper MY.EXTERNAL.IP:2181 --describe --topic test123
--> Topic:test123 PartitionCount:1 ReplicationFactor:1 Configs:
Topic: test123 Partition: 0 Leader: 0 Replicas: 0 Isr: 0
我重新尝试了这个测试,我的server.log表明领导者在0:
...
[2015-06-16 21:58:04,498] INFO 0 successfully elected as leader (kafka.server.ZookeeperLeaderElector)
[2015-06-16 21:58:04,642] INFO Registered broker 0 at path /brokers/ids/0 with address MY.EXTERNAL.IP:9092. (kafka.utils.ZkUtils$)
[2015-06-16 21:58:04,670] INFO [Kafka Server 0], started (kafka.server.KafkaServer)
[2015-06-16 21:58:04,736] INFO New leader is 0 (kafka.server.ZookeeperLeaderElector$LeaderChangeListener)
当我从制作人发送消息时,我在日志中看到了这个错误:
[2015-06-16 22:18:24,584] ERROR [KafkaApi-0] error when handling request Name: TopicMetadataRequest; Version: 0; CorrelationId: 7; ClientId: console-producer; Topics: test123 (kafka.server.KafkaApis)
kafka.admin.AdminOperationException: replication factor: 1 larger than available brokers: 0
at kafka.admin.AdminUtils$.assignReplicasToBrokers(AdminUtils.scala:70)
我认为这意味着由于某种原因无法找到经纪人?我很困惑这意味着......
答案 0 :(得分:27)
对于最新版本的Kafka(撰写本文时为0.10.0),您根本不想使用advertised.host.name
。事实上,即使是[文档]也指出advertised.host.name
已被弃用。此外,Kafka不仅将其用作生产者/消费者的“广告”主机名,而且还用于其他经纪人(在多经纪人环境中)...这是一种如果你使用不同的(也许是内部的)DNS来代理经纪人,你会感到痛苦......而且你真的不想开始向经纪人的个人/etc/hosts
添加条目(ew!)
因此,基本上,您希望代理使用内部名称,但仅为生产者和使用者使用外部FQDN 。为此,您将更新advertised.listeners
。
答案 1 :(得分:25)
将advertised.host.name设置为主机名称,而不是IP地址。默认设置是使用getCanonicalHostName()返回 FQDN ,但这只是尽力而为并退回到IP。请参阅java docs for getCanonicalHostName()。
诀窍是让主机名始终解析为正确的IP。对于小型环境,我通常会在/ etc / hosts中设置所有内部IP的所有主机。这样,所有机器都知道如何通过内部网络按名称相互通信。实际上,现在也要按名称配置Kafka客户端,而不是IP。如果管理所有/ etc / hosts文件是一个负担,那么设置一个内部DNS服务器来集中它,但是内部DNS应该返回内部IP 。这些选项中的任何一个都应该比在各种计算机上的各种配置文件中分散IP地址的工作少。
一旦所有内容都按名称进行通信,剩下的就是使用外部IP配置外部DNS,一切正常。这包括使用服务器名称配置Kafka客户端,而不是IP。
答案 2 :(得分:16)
总而言之,解决方法是通过NAT添加路由,以便机器可以访问自己的外部IP地址。
Zookeeper使用它在advertised.host.name中找到的地址来告诉客户端在哪里找到代理以及与代理本身进行通信。报告的错误并没有使这一点变得非常清楚,而且令人困惑,因为客户端在打开TCP连接时没有问题。
答案 3 :(得分:6)
从上面获取提示:对于我的单个节点(在学习的同时),我将具有文本“advertised.host.name”的server.properties文件修改为@drawable/icon
。所以最后它看起来像这样
advertised.host.name = 127.0.0.1
在启动制作人时,它仍会显示警告,但现在它至少工作,而我可以看到消费者终端上的消息完美地出现
答案 4 :(得分:1)
在安装了Kafka的计算机上,检查它是否已启动并正在运行。错误状态,0个代理可用,这意味着Kafka没有启动并运行。
在linux机器上,您可以使用netstat命令检查服务是否正在运行。
netstat -an | grep port_kafka_is_Listening(默认为9092)
答案 5 :(得分:0)
CONF / server.properties:
主机名
DEPRECATED:仅在未设置listeners
时使用。请改用listeners
。经纪人的主持人。如果设置了此选项,则只会绑定到此地址。如果未设置,则将绑定到所有接口