简体   繁体   English

为什么Kafka经纪人可以自我连接?

[英]Why Kafka broker connects to itself?

Few days ago I tried to configure Kafka Docker container with Docker Compose and port mapping and discover interesting behavior which I do not fully understand: 几天前,我尝试使用Docker Compose和端口映射配置Kafka Docker容器,并发现有趣的行为,但我并未完全理解:

Kafka broker seems to connect to itself. 卡夫卡经纪人似乎与自己建立了联系。 Why ? 为什么呢

My set up is: 我的设置是:

  • Ubuntu 14.04, Docker 1.13.1, Docker-Compose 1.5.2 Ubuntu 14.04,Docker 1.13.1,Docker-Compose 1.5.2
  • Kafka 0.10 listens on port 9092, this port is exposed by container. Kafka 0.10侦听端口9092,此端口由容器暴露。
  • In Docker Compose I have port mapping from container port 9092 to local port 4005. 在Docker Compose中,我有从容器端口9092到本地端口4005的端口映射。
  • I configured host name of my Docker Host machine and local port from Compose in advertised.listeners ( docker-host:4005 ) since broker should be visible from my company network. 我在advertised.listeners( docker-host:4005 )中通过Compose配置了Docker主机的主机名和本地端口,因为代理应该从我的公司网络中可见。

With this set up when I try to send/fetch data to/from Kafka, all attempts end up with: 有了这个设置,当我尝试向Kafka发送数据或从Kafka获取数据时,所有尝试都会以以下形式结束:

Topic metadata fetch included errors: {topic_name=LEADER_NOT_AVAILABLE}

After trying various combinations of ports and host names in advertised.listeners , I discovered that sole working combination is localhost:9092 . 在尝试了advertised.listeners中端口和主机名的各种组合之后,我发现唯一localhost:9092组合是localhost:9092 Any attempt to change hostname or port led to the error mentioned above. 尝试更改主机名或端口会导致上述错误。
This made me think that Kafka tries to connect to address configured in advertised.listeners and this is somehow related to topic metadata. 这使我认为Kafka尝试连接到advertised.listeners配置的地址,这与主题元数据有关。

So inside Docker container I did: 所以在Docker容器中我做了:

  • redirect traffic to "docker-host" to loopback 将流量重定向到“ docker-host”进行环回
    echo "127.0.0.1 $ADVERTISED_HOST" >> /etc/hosts
  • configure Kafka to listen on all interfaces and port (exact as advertised) 将Kafka配置为在所有接口和端口上进行侦听(与所宣传的完全相同)
    sed -r -i "s/#(listeners)=(.*)/\\1=PLAINTEXT:\\/\\/0.0.0.0:4005/g" $KAFKA_HOME/config/server.properties
  • advertise "docker-host" and external port 宣传“ docker-host”和外部端口
    sed -r -i "s/#(advertised.listeners)=(.*)/\\1=PLAINTEXT:\\/\\/$ADVERTISED_HOST:4005/g" $KAFKA_HOME/config/server.properties

And now it works like a charm. 现在,它就像一种魅力。

However I still do not understand: 但是我还是不明白:

  1. Why Kafka broker might need to connect to itself via address configured in advertised.listeners ? 为什么Kafka经纪人可能需要通过advertised.listeners配置的地址连接到自身?
  2. Is there a way to disable this or at least configure it to use address from 'listeners' property (with default Kafka port) ? 有没有办法禁用此功能或至少将其配置为使用“ listeners”属性中的地址(带有默认的Kafka端口)?

UPD Worth to mention, following setup does not work: Kafka listens on 0.0.0.0:9092 , advertised listener is configured to docker-host:4005 . UPD值得一提的是,以下设置无效:Kafka侦听0.0.0.0:9092 ,播发的侦听器配置为docker-host:4005
In this case whenever consumer or producer connects to kafka it receives LEADER_NOT_AVAILABLE. 在这种情况下,只要消费者或生产者连接到kafka,它都会收到LEADER_NOT_AVAILABLE。 There is also connection shown by netstat (within container) to docker-host:4005 in state SYN_SENT. netstat(在容器中)还显示了到状态为SYN_SENT的docker-host:4005的连接。

UPD 2 Looks like there is similar problem with Kafka but inside AWS described here . UPD 2看起来Kafka也有类似的问题,但此处描述 AWS内部。
Difference is that in my case I want to use different Kafka port. 区别在于我要使用其他Kafka端口。

UPD 3 Ok, the reason why setup mentioned in the first UPD paragraph does not work is - UFW, for some reasons it blocks traffic which goes from docker container to itself via host machine. UPD 3好吧,第一段UPD中提到的设置不起作用的原因是-UFW,由于某些原因,它阻止了从Docker容器通过主机流向自身的流量。

Why Kafka broker might need to connect to itself via address configured in advertised.listeners ? 为什么Kafka经纪人可能需要通过advertised.listeners中配置的地址连接到自身?

When a Kafka broker is first connected by a client, it replies back with the address that it expects that client to use in the future to talk to the broker. 当Kafka经纪人首次与客户建立联系时,它会用希望该客户将来与经纪人对话的地址进行回复。 This is what is set in the advertised.listeners property. 这是在advertised.listeners属性中设置的。 If you don't set this property, the value from listeners will be used instead (which answers your second question). 如果您未设置此属性,则将改用来自侦听器的值(它将回答您的第二个问题)。

So your "issue" is, that remote clients connect to yourhost:9092, reach the Kafka broker, because you forwarded the port, the broker then responds with "you can reach me at localhost:9092" and when the client sends the next packet there it just connects back to itself. 因此,您的“问题”是,远程客户端连接到yourhost:9092,到达Kafka代理,因为您转发了端口,该代理然后响应“您可以在localhost:9092与我联系”,并且当客户端发送下一个数据包时在那里,它只是重新连接到自身。 The metadata is not really related here, its just the first request that gets made. 元数据在这里并不真正相关,它只是第一个发出的请求。 Your solution is correct for this setup I think, have Kafka listen on local interfaces and set the advertised.listeners to the host that someone from your company network would connect to. 我认为您的解决方案对此设置是正确的,让Kafka侦听本地接口并将advertised.listeners设置为公司网络中某人将连接到的主机。 I don't 100% know if the broker needs to connect to itself as well, pretty sure thats not the case though. 我不是100%知道经纪人是否也需要连接到自身,但是可以肯定的是事实并非如此。 I think your setup would also work without the entry of the external hostname in your /etc/hosts file. 我认为您的设置也可以在没有在/ etc / hosts文件中输入外部主机名的情况下工作。

Is there a way to disable this or at least configure it to use address from 'listeners' property (with default Kafka port) ? 有没有办法禁用此功能或至少将其配置为使用“ listeners”属性中的地址(带有默认的Kafka端口)?

see above 往上看

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM