You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker内命令行创建Kafka topic正常,同命令写入Shell脚本执行失败

问题根因

docker compose up -d仅保证容器进入运行状态,不会等待Kafka服务完成初始化。Kafka启动时需要先和ZooKeeper建立连接、完成元数据同步、启动端口监听,整个过程需要几秒到十几秒不等。脚本执行时两个命令无缝衔接,此时Kafka还未完成初始化,就会返回Broker不可用的报错。手动执行命令时,两条命令之间的输入间隔刚好等Kafka完成初始化,所以可以执行成功。

可行解决方案

方案1:脚本内添加服务等待逻辑(最通用,无需修改docker-compose配置)

在脚本中添加端口检测逻辑,等待Kafka服务就绪后再执行创建命令,修改后的init.sh参考如下:

#!/bin/zsh
docker compose up -d

# 等待Kafka服务就绪,最多等待30秒
MAX_WAIT=30
WAIT_CNT=0
while ! nc -z localhost 29092; do
  if [ ${WAIT_CNT} -ge ${MAX_WAIT} ]; then
    echo "Kafka启动超时,topic创建失败"
    exit 1
  fi
  echo "等待Kafka服务启动中..."
  sleep 1
  WAIT_CNT=$((WAIT_CNT+1))
done

# 服务就绪后执行创建命令
docker exec kafka kafka-topics --create --bootstrap-server localhost:29092 --partitions 1 --replication-factor 1 --topic Test

如果宿主机未安装nc工具,也可以替换为容器内部的健康检查命令:

while ! docker exec kafka kafka-broker-api-versions --bootstrap-server localhost:9092 > /dev/null 2>&1; do
  # 超时逻辑同上
done

方案2:通过docker-compose健康检查控制启动流程(更规范)

在docker-compose.yml的kafka服务配置中添加健康检查规则,配置参考:

kafka:
    image: confluentinc/cp-kafka:latest
    container_name: kafka
    depends_on:
      - zookeeper
    ports:
      - "29092:29092"
    # 新增健康检查配置
    healthcheck:
      test: ["CMD", "kafka-broker-api-versions", "--bootstrap-server", "localhost:9092"]
      interval: 2s
      timeout: 2s
      retries: 15
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

对应修改init.sh脚本的启动命令,让docker等待所有服务健康检查通过后再返回:

#!/bin/zsh
# 替换原有docker compose up -d
docker compose up -d --wait

docker exec kafka kafka-topics --create --bootstrap-server localhost:29092 --partitions 1 --replication-factor 1 --topic Test

优化建议

因为创建topic的命令是在kafka容器内部执行,不需要走宿主机的端口映射,可将命令中的--bootstrap-server localhost:29092修改为--bootstrap-server kafka:9092,使用容器内部网络访问,链路更稳定。

内容的提问来源于stack exchange,提问作者Nando Machado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 00:09:00