Spring Boot CQRS项目Kafka生产者消费者Docker部署连接异常求助
Spring Boot CQRS项目Docker环境下Kafka连接问题解决方案
问题现象
- 执行
docker-compose --build启动所有容器后,Postman请求http://localhost:5000/api/v1/openBankAccount一直处于"Sending request..."状态 - Producer(account-cmd)日志持续出现:
[Producer clientId=producer-1] Bootstrap broker localhost:9092 (id: -1 rack: null) disconnected - Consumer(account-query)日志持续出现:
[Consumer clientId=consumer-bankaccConsumer-4, groupId=bankaccConsumer] Bootstrap broker localhost:9092 (id: -1 rack: null) disconnected - 最终Producer抛出超时错误:
org.springframework.kafka.kafkaexception : Send failed Caused by: org.apache.kafka.common.errors.TimeoutException: Topic AccountOpenedEvent not present in metadata after 60000 ms.
核心原因
- 应用容器内仍在尝试连接
localhost:9092,而非Kafka服务名kafka:9092(Docker容器内localhost指向自身,而非Kafka容器) - 服务启动顺序问题:应用在Kafka完全就绪前就已启动,导致连接失败
- 目标Topic未自动创建,Producer无法发送消息
修复步骤
1. 确保应用Kafka配置正确
检查account-cmd和account-query的配置文件(application.yml/application.properties),移除任何硬编码的spring.kafka.bootstrap-servers=localhost:9092配置,确保Docker Compose的环境变量覆盖生效:
- account-cmd环境变量中,确保
spring.kafka.bootstrap-servers=kafka:9092(或spring.kafka.producer.bootstrap-servers=kafka:9092)正确设置 - account-query环境变量中,确保
spring.kafka.bootstrap-servers=kafka:9092(或spring.kafka.consumer.bootstrap-servers=kafka:9092)正确设置
2. 给Kafka添加健康检查,确保服务就绪
修改docker-compose.yml中Kafka服务的配置,添加healthcheck及自动创建Topic的配置:
kafka: image: 'bitnami/kafka:latest' ports: - '9092:9092' - '9093:9093' environment: - KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181 - ALLOW_PLAINTEXT_LISTENER=yes - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CLIENT:PLAINTEXT,EXTERNAL:PLAINTEXT - KAFKA_CFG_LISTENERS=CLIENT://:9092,EXTERNAL://:9093 - KAFKA_CFG_ADVERTISED_LISTENERS=CLIENT://kafka:9092,EXTERNAL://localhost:9093 - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=CLIENT - KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true # 开启Topic自动创建 depends_on: - zookeeper networks: - bankAccount healthcheck: test: ["CMD", "kafka-topics.sh", "--list", "--bootstrap-server", "localhost:9092"] timeout: 10s retries: 5 start_period: 20s
同时修改account-cmd和account-query的depends_on配置,等待依赖服务就绪后再启动:
# account-cmd的depends_on配置 depends_on: zookeeper: condition: service_healthy kafka: condition: service_healthy mongodb: condition: service_started # account-query的depends_on配置 depends_on: zookeeper: condition: service_healthy kafka: condition: service_healthy database: condition: service_healthy
3. 验证网络连通性
进入account-cmd容器,测试能否解析并连通kafka服务:
# 测试域名解析 docker exec -it <account-cmd-container-id> ping kafka # 测试端口连通性 docker exec -it <account-cmd-container-id> telnet kafka 9092
如果无法连通,检查所有服务是否在同一个bankAccount网络中。
4. 手动创建Topic(可选)
如果自动创建Topic仍失败,可手动创建AccountOpenedEvent Topic:
# 进入Kafka容器 docker exec -it <kafka-container-id> kafka-topics.sh --create --topic AccountOpenedEvent --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1
验证修复
重启所有容器:
docker-compose down docker-compose --build up
再次用Postman发送请求,检查Producer/Consumer日志是否正常,是否能成功发送/接收消息。
内容的提问来源于stack exchange,提问作者Sercan Noyan Germiyanoğlu
相关产品推荐
相关产品推荐

