首页 > 解决方案 > 卡夫卡码头工人和 LEADER_NOT_AVAILABLE

问题描述

我使用以下 Kafka Docker 映像:https ://hub.docker.com/r/wurstmeister/kafka/

我可以使用以下属性启动 Apache Kafka:

<KAFKA_ADVERTISED_HOST_NAME>${local.ip}</KAFKA_ADVERTISED_HOST_NAME>
<KAFKA_ADVERTISED_PORT>${kafka.port}/KAFKA_ADVERTISED_PORT>     
<KAFKA_ZOOKEEPER_CONNECT>zookeeper:2181</KAFKA_ZOOKEEPER_CONNECT>   
<KAFKA_MESSAGE_MAX_BYTES>15000000</KAFKA_MESSAGE_MAX_BYTES>

但我在尝试将消息发送到主题时看到以下警告:

WARN 9248 --- [ad | producer-1] org.apache.kafka.clients.NetworkClient   : [Producer clientId=producer-1] Error while fetching metadata with correlation id 4 : {post.sent=LEADER_NOT_AVAILABLE}

我在互联网上看到一些文章告诉这个问题可能与旧属性有关,例如KAFKA_ADVERTISED_HOST_NAMEandKAFKA_ADVERTISED_PORT我应该重新配置为KAFKA_ADVERTISED_LISTENERSand KAFKA_LISTENERS。但是当我使用以下属性启动 Kafka 容器时:

<KAFKA_ADVERTISED_LISTENERS>PLAINTEXT://${local.ip}:${kafka.port}</KAFKA_ADVERTISED_LISTENERS>
<KAFKA_LISTENERS>PLAINTEXT://${local.ip}:${kafka.port}</KAFKA_LISTENERS>                            
<KAFKA_ZOOKEEPER_CONNECT>zookeeper:2181</KAFKA_ZOOKEEPER_CONNECT>   
<KAFKA_MESSAGE_MAX_BYTES>15000000</KAFKA_MESSAGE_MAX_BYTES>

我的应用程序无法连接到 Kafka:

2018-08-25 16:20:57.407  INFO 17440 --- [           main] o.a.kafka.common.utils.AppInfoParser     : Kafka version : 1.1.0
2018-08-25 16:20:57.408  INFO 17440 --- [           main] o.a.kafka.common.utils.AppInfoParser     : Kafka commitId : fdcf75ea326b8e07
2018-08-25 16:20:58.513  WARN 17440 --- [| adminclient-1] org.apache.kafka.clients.NetworkClient   : [AdminClient clientId=adminclient-1] Connection to node -1 could not be established. Broker may not be available.
2018-08-25 16:20:59.567  WARN 17440 --- [| adminclient-1] org.apache.kafka.clients.NetworkClient   : [AdminClient clientId=adminclient-1] Connection to node -1 could not be established. Broker may not be available.

如何正确重新配置 Docker Kafka 以便能够使用KAFKA_ADVERTISED_LISTENERSKAFKA_LISTENERS

标签: dockerapache-kafka

解决方案


从这篇很棒的帖子中,这里有一个关于这些属性的很好的解释:

监听器是 Kafka 绑定的接口。ADVERTISED_LISTENERS 是客户端可以连接的方式。

当您的应用程序连接到来自 LISTENERS 的地址之一时, Kafka会将对应的 KAFKA_ADVERTISED_LISTENER 返回给您选择的那个 LISTENER。返回的 KAFKA_ADVERTISED_LISTENER 是您的应用程序真正用于与 Kafka 通信的地址。

因此,您必须在应用程序中使用您在PLAINTEXT的 LISTENERS Kafka 属性上设置的内容。

如您所说,使用此配置:

<KAFKA_ADVERTISED_LISTENERS>PLAINTEXT://${local.ip}:${kafka.port}</KAFKA_ADVERTISED_LISTENERS>
<KAFKA_LISTENERS>PLAINTEXT://${local.ip}:${kafka.port}</KAFKA_LISTENERS>

您必须在您的应用程序上使用:

正如您在 Kafka docker ${local.ip}:${kafka.port}上使用的那样,您必须获取分配的 kafka docker 容器 IP 并在您的应用程序中使用它

只是为了填充此场景的变量,假设您的 kafka docker 容器 IP 192.250.0.1 并且使用的 kafka 端口是 9092,因此您的应用程序 bootstrap.servers 属性将为:192.250.0.1:9092

当您尝试使用 kafka 的侦听器之一进行连接时,这里有一个命令可以查看 Kafka 返回给您的内容:

$ kafkacat -b 192.250.0.1:9092 -L

kafkacat是一个非常有用的测试和调试 kafka 的工具。


推荐阅读