【问题标题】:kafka-node can't connect to kafka server in local environmentkafka-node 无法连接到本地环境中的 kafka 服务器
【发布时间】:2020-01-18 22:49:25
【问题描述】:

我使用 docker inspect 命令启动了一个 kafka(2.2.0 版)docker 容器。

kafka 配置是

Using ZOOKEEPER_CONNECT=172.17.0.2:2181
Using KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://172.17.0.6:9092
Using KAFKA_BROKER=172.17.0.4:9092

显示网络设置

 "NetworkSettings": {
            "Ports": {
                "8778/tcp": null,
                "9092/tcp": null,
                "9779/tcp": null
            },
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.6",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:06"

我还查找了 kafka 容器中的主题。

./zkCli.sh
ls /brokers/topics

主题如下所示

[connect-status, dbserver1.public.dumb_table, my-connect-offsets, __consumer_offsets, my-connect-configs]

最后我启动了一个节点应用程序来连接到 kafka 但失败了。 (https://github.com/SOHU-Co/kafka-node#kafkaclient)

const kafka = require('kafka-node');
const bp = require('body-parser');

try {
  const Consumer = kafka.HighLevelConsumer;
  const client = new kafka.KafkaClient({kafkaHost: '172.17.0.6:9092'});
  let consumer = new kafka.Consumer(
    client,
    [{ topic: "dbserver1.public.dumb_table", partition: 0 }],
    {
      autoCommit: true,
      fetchMaxWaitMs: 1000,
      fetchMaxBytes: 1024 * 1024,
      encoding: 'utf8',
      fromOffset: false
    }
  );
  consumer.on('ready', function () {
        console.log('consumer ready');

  });
  consumer.on('message', async function(message) {
    console.log('here');
    console.log(
      'kafka-> ',
      message.value
    );
  })
  consumer.on('error', function(err) {
    console.log('error', err);
  });
}
catch(e) {
  console.log(e);
}

如果kafkaHost配置为'172.17.0.6:9092',则抛出错误

{ Error: connect ENETUNREACH 172.17.0.6:9092
    at Object._errnoException (util.js:992:11)
    at _exceptionWithHostPort (util.js:1014:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1186:14)
  code: 'ENETUNREACH',
  errno: 'ENETUNREACH',
  syscall: 'connect',
  address: '172.17.0.6',
  port: 9092 }

如果kafkaHost配置为'localhost:9092',则会抛出错误

{ TimeoutError: Request timed out after 30000ms
at new TimeoutError (/Users/xisizhe/Documents/projects/game/server/node_modules/kafka-node/lib/errors/TimeoutError.js:6:9)
at Timeout.setTimeout [as _onTimeout] (/Users/xisizhe/Documents/projects/game/server/node_modules/kafka-node/lib/kafkaClient.js:491:14)
at ontimeout (timers.js:498:11)
at tryOnTimeout (timers.js:323:5)
at Timer.listOnTimeout (timers.js:290:5) message: 'Request timed out after 30000ms' }

【问题讨论】:

  • 为什么不宣传 localhost:9092?您不需要 Kafka 或 Zookeeper 上的 Docker IP。您可以使用 Confluent 中现有的 Docker 撰写文件,它们无需重新配置即可工作confluent.io/blog/kafka-listeners-explained
  • 我试过 docker run -it --name kafka -p 9092:9092 -e ADVERTISED_HOST_NAME=localhost --link zookeeper:zookeeper debezium/kafka 但日志一直让我感到温暖:2019-09-18 05 :06:07,641 - WARN [Controller-1-to-broker-1-send-thread:NetworkClient@725] - [Controller id=1, targetBrokerId=1] 连接到节点 1 (localhost/127.0.0.1:9092) 可以不成立。经纪人可能不可用。
  • docker run -it --name kafka -p 9092:9092 -e ADVERTISED_HOST_NAME=localhost --link zookeeper:zookeeper -e ZOOKEEPER_IP=172.17.0.2 debezium/kafka 也不起作用,仍然有错误消息:无法建立与节点 1 (localhost/127.0.0.1:9092) 的连接。
  • ADVERTISED_HOST_NAME 属性已弃用。你从哪里得到这个命令?
  • 另外,你会使用--link zookeeper:zookeeper -e ZOOKEEPER_IP=zookeeper,但你真的应该只使用 Docker compose 而不是手动运行 Kafka 和 Zookeeper

标签: node.js docker apache-kafka


【解决方案1】:

如果kafkaHost配置为'172.17.0.6:9092',则抛出错误

您的 Node 应用程序是否也在 Docker 中运行?如果是这样,您将不会看到该错误。


看起来你做了docker inspect,然后从中复制了一些 IP,我认为在我遇到的任何 Debezium / Docker+Kafka 教程中都不需要这样做。

您想要 主机 IP(您的 Mac);在 Docker 及其托管的 VM 网络之外(您的主机无法将请求路由到该子网)。


例如在我的 Mac 上,我检查了一个随机容器(恰好是 Kafka)

docker inspect ee708cf11010 | grep IPAddress
        "SecondaryIPAddresses": null,
        "IPAddress": "",
                "IPAddress": "172.18.0.3",
                "IPAddress": "172.20.0.3",

我无法连接到那些

nc -vz 172.20.0.3 9092
# ... hangs

但是我可以连接到暴露的端口就好了

nc -vz localhost 9092
found 0 associations
found 1 connections:
     1: flags=82<CONNECTED,PREFERRED>
    outif lo0
    src ::1 port 51180
    dst ::1 port 9092
    rank info not available
    TCP aux info available

Connection to localhost port 9092 [tcp/XmlIpcRegSvc] succeeded!

或者

  • 使用我的主机名和nc -vz $(hostname -f) 9092
  • 我的局域网IPnc -vz 192.168.1.105 9092

由于Debezium tutorial statesADVERTISED_HOST_NAME 需要是您的主机的主机名或外部 IP。主机名最简单,您可以像这样将其传递给 docker。

docker run -it --name kafka -p 9092:9092 -e ADVERTISED_HOST_NAME=$(hostname -f) --link zookeeper:zookeeper debezium/kafka

您的节点代码仍然可以使用localhost:9092,但无论如何传递正确的 IP/主机名会更合乎逻辑。


除此之外:您不需要使用 Debezium/kafka 容器来使用实际的 Debezium 连接器,因为它刚刚启动 Kafka。所以,这是我关于如何在 Docker 中为在 Docker 和主机中运行的生产者/消费者应用程序正确配置 Kafka 的另一个答案

Connect to Kafka running in Docker from local machine

【讨论】:

  • 终于 docker run -it --name kafka -p 9092:9092 -e ADVERTISED_HOST_NAME=$(hostname -f) --link zookeeper:zookeeper debezium/kafka 工作,非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-28
  • 1970-01-01
  • 2018-04-13
  • 2023-02-01
  • 2019-04-28
  • 2020-09-09
  • 2017-10-29
相关资源
最近更新 更多