Docker部署双Kafka Broker通信故障排查与求助
Kafka Docker集群Broker间通信失败及配置错误解决
问题背景
尝试用Docker Compose搭建两个Kafka Broker实现互相通信,但先启动的Broker无法定位另一个Broker,同时使用kafkajs发送消息时提示KafkaJSNonRetriableError: Replication-factor is invalid。
初始Docker Compose配置
version: '3.8' services: zookeeper: image: "bitnami/zookeeper:latest" ports: - "2181:2181" environment: - ALLOW_ANONYMOUS_LOGIN=yes - ZOOKEEPER_CLIENT_PORT=2181 - ZOOKEEPER_TICK_TIME=2000 tmpfs: "/datalog" kafka-1: image: "bitnami/kafka:latest" container_name: "kafka-1" ports: - "9094:9094" depends_on: - zookeeper restart: always environment: - KAFKA_BROKER_ID=1 - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 - KAFKA_LISTENERS=PLAINTEXT://:9094 - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9094 - KAFKA_DEFAULT_REPLICATION_FACTOR=2 - KAFKA_NUM_PARTITIONS=2 - ALLOW_PLAINTEXT_LISTENER=yes kafka-2: image: "bitnami/kafka:latest" container_name: "kafka-2" ports: - "9095:9095" depends_on: - zookeeper restart: always environment: - KAFKA_BROKER_ID=2 - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 - KAFKA_LISTENERS=PLAINTEXT://:9095 - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9095 - KAFKA_DEFAULT_REPLICATION_FACTOR=2 - KAFKA_NUM_PARTITIONS=2 - ALLOW_PLAINTEXT_LISTENER=yes
初始错误日志
kafka-2 | [[2022-10-24 15:41:47,131] INFO [Controller id=2, targetBrokerId=1] Client requested connection close from node 1 (org.apache.kafka.clients.NetworkClient) kafka-2 | [2022-10-24 15:41:47,232] INFO [Controller id=2, targetBrokerId=1] Node 1 disconnected. (org.apache.kafka.clients.NetworkClient) kafka-2 | [2022-10-24 15:41:47,232] WARN [Controller id=2, targetBrokerId=1] Connection to node 1 (/127.0.0.1:9094) could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient) kafka-2 | [2022-10-24 15:41:47,232] WARN [RequestSendThread controllerId=2] Controller 2's connection to broker 127.0.0.1:9094 (id: 1 rack: null) was unsuccessful (kafka.controller.RequestSendThread) kafka-2 | java.io.IOException: Connection to 127.0.0.1:9094 (id: 1 rack: null) failed. kafka-2 | at org.apache.kafka.clients.NetworkClientUtils.awaitReady(NetworkClientUtils.java:70) kafka-2 | at kafka.controller.RequestSendThread.brokerReady(ControllerChannelManager.scala:291) kafka-2 | at kafka.controller.RequestSendThread.doWork(ControllerChannelManager.scala:245) kafka-2 | at kafka.utils.ShutdownableThread.run(ShutdownableThread.scala:96)
发送消息时同步出现错误:KafkaJSNonRetriableError: Replication-factor is invalid
修改配置后的新问题
添加内部通信监听器后,新配置如下:
version: '3.8' services: dynamodb-local-express-bp: command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data" image: "amazon/dynamodb-local:latest" container_name: dynamodb-local-express-bp ports: - "8000:8000" volumes: - "./docker/dynamodb:/home/dynamodblocal/data" working_dir: /home/dynamodblocal zookeeper: image: "bitnami/zookeeper:latest" ports: - "2181:2181" environment: - ALLOW_ANONYMOUS_LOGIN=yes - ZOOKEEPER_CLIENT_PORT=2181 - ZOOKEEPER_TICK_TIME=2000 tmpfs: "/datalog" kafka-1: image: "bitnami/kafka:latest" container_name: "kafka-1" expose: - 9092 ports: - "9094:9094" depends_on: - zookeeper restart: always environment: - KAFKA_BROKER_ID=1 - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 - KAFKA_CFG_LISTENERS=PLAINTEXT://:9094,INTERNAL://:9092 - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9094,INTERNAL://kafka-1:9092 - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,INTERNAL:PLAINTEXT - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=INTERNAL - KAFKA_CFG_DEFAULT_REPLICATION_FACTOR=2 - KAFKA_CFG_NUM_PARTITIONS=2 - ALLOW_PLAINTEXT_LISTENER=yes kafka-2: image: "bitnami/kafka:latest" container_name: "kafka-2" ports: - "9095:9095" depends_on: - zookeeper restart: always environment: - KAFKA_BROKER_ID=2 - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 - KAFKA_CFG_LISTENERS=PLAINTEXT://:9095,INTERNAL://:9092 - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9095,INTERNAL://kafka-1:9092 - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,INTERNAL:PLAINTEXT - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=INTERNAL - KAFKA_CFG_DEFAULT_REPLICATION_FACTOR=2 - KAFKA_CFG_NUM_PARTITIONS=2 - ALLOW_PLAINTEXT_LISTENER=yes # - KAFKA_BROKER_ID=2 # - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 # - KAFKA_LISTENERS=PLAINTEXT://:9095 # - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9095 # - KAFKA_DEFAULT_REPLICATION_FACTOR=2 # - KAFKA_NUM_PARTITIONS=2 # - ALLOW_PLAINTEXT_LISTENER=yes
出现启动失败错误:
[2022-10-24 18:59:06,286] ERROR [KafkaServer id=2] Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer) kafka-2 | java.lang.IllegalArgumentException: requirement failed: Configured end points kafka-1:9092 in advertised listeners are already registered by broker 1 kafka-2 | at scala.Predef$.require(Predef.scala:281) kafka-2 | at kafka.server.KafkaServer.$anonfun$createBrokerInfo$3(KafkaServer.scala:512) kafka-2 | at kafka.server.KafkaServer.$anonfun$createBrokerInfo$3$adapted(KafkaServer.scala:510) kafka-2 | at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62) kafka-2 | at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55) kafka-2 | at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49) kafka-2 | at kafka.server.KafkaServer.createBrokerInfo(KafkaServer.scala:510) kafka-2 | at kafka.server.KafkaServer.startup(KafkaServer.scala:331) kafka-2 | at kafka.Kafka$.main(Kafka.scala:109) kafka-2 | at kafka.Kafka.main(Kafka.scala)
问题解决
1. 初始通信失败原因
初始配置中,KAFKA_ADVERTISED_LISTENERS设置为127.0.0.1:9094/9095,导致Broker在Docker容器内部互相访问时,尝试连接自身容器的127.0.0.1而非另一个Broker的容器地址,无法建立跨容器连接。
2. 修改配置后的错误原因
kafka-2的INTERNAL监听器地址错误设置为kafka-1:9092,与kafka-1的内部注册地址重复,导致ZooKeeper中端点冲突,启动失败。
正确配置方案
调整两个Kafka节点的内部监听器地址,确保每个节点的内部地址唯一,同时保留外部访问的监听器:
version: '3.8' services: dynamodb-local-express-bp: command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data" image: "amazon/dynamodb-local:latest" container_name: dynamodb-local-express-bp ports: - "8000:8000" volumes: - "./docker/dynamodb:/home/dynamodblocal/data" working_dir: /home/dynamodblocal zookeeper: image: "bitnami/zookeeper:latest" ports: - "2181:2181" environment: - ALLOW_ANONYMOUS_LOGIN=yes - ZOOKEEPER_CLIENT_PORT=2181 - ZOOKEEPER_TICK_TIME=2000 tmpfs: "/datalog" kafka-1: image: "bitnami/kafka:latest" container_name: "kafka-1" expose: - 9092 ports: - "9094:9094" depends_on: - zookeeper restart: always environment: - KAFKA_BROKER_ID=1 - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 - KAFKA_CFG_LISTENERS=PLAINTEXT://:9094,INTERNAL://:9092 - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9094,INTERNAL://kafka-1:9092 - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,INTERNAL:PLAINTEXT - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=INTERNAL - KAFKA_CFG_DEFAULT_REPLICATION_FACTOR=2 - KAFKA_CFG_NUM_PARTITIONS=2 - ALLOW_PLAINTEXT_LISTENER=yes kafka-2: image: "bitnami/kafka:latest" container_name: "kafka-2" expose: - 9092 ports: - "9095:9095" depends_on: - zookeeper restart: always environment: - KAFKA_BROKER_ID=2 - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 - KAFKA_CFG_LISTENERS=PLAINTEXT://:9095,INTERNAL://:9092 - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9095,INTERNAL://kafka-2:9092 - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,INTERNAL:PLAINTEXT - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=INTERNAL - KAFKA_CFG_DEFAULT_REPLICATION_FACTOR=2 - KAFKA_CFG_NUM_PARTITIONS=2 - ALLOW_PLAINTEXT_LISTENER=yes
关键修改点
- 将kafka-2的
INTERNAL监听器地址改为kafka-2:9092,与kafka-1的kafka-1:9092区分,避免端点冲突。 - 给kafka-2添加
expose: -9092,确保容器内部可访问该端口。 - 通过
INTER_BROKER_LISTENER_NAME指定INTERNAL为Broker间通信的监听器,让Broker通过容器内部地址通信,解决跨容器连接问题。
复制因子错误解决
Broker集群正常启动后,KafkaJSNonRetriableError: Replication-factor is invalid错误会自动消失,此时集群有2个可用Broker,满足default.replication.factor=2的配置要求。
内容的提问来源于stack exchange,提问作者blu
相关产品推荐
相关产品推荐

