Docker环境下Kafka Producer发消息正常但Consumer无法消费求助
Kafka Docker环境下Consumer无法接收消息的排查与解决
问题描述
使用Docker Compose运行微服务应用,通过Kafka实现两个微服务间的消息通信。Producer已确认成功向Topic发送消息(日志已验证),但Docker环境中的Consumer无法接收消息,本地运行环境一切正常。
当前docker-compose.yml配置如下:
services: zookeeper: image: wurstmeister/zookeeper container_name: zookeeper-container ports: - "2181:2181" networks: - my-movie-network kafka: image: wurstmeister/kafka container_name: kafka-container ports: - "9092:9092" environment: KAFKA_ADVERTISED_HOST_NAME: kafka KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9092,OUTSIDE://config-server:9093 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT KAFKA_LISTENERS: INSIDE://0.0.0.0:9092,OUTSIDE://0.0.0.0:9093 KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_CREATE_TOPICS: "baeldung:1:1" networks: - my-movie-network authentication-service: image: tejajagadeep/movie-app-authentication-service container_name: authentication-container build: context: authentication-service dockerfile: Dockerfile environment: - spring.kafka.consumer.bootstrap-servers=kafka:9092 ports: - "8090:8090" networks: - my-movie-network links: - kafka userprofile-service: image: tejajagadeep/movie-app-userprofile-service container_name: userprofile-container build: context: userprofile-service dockerfile: Dockerfile environment: - spring.kafka.producer.bootstrap-servers=kafka:9092 ports: - "8092:8092" networks: - my-movie-network links: - kafka
排查与解决步骤
1. 修正Kafka监听器配置
当前Kafka的KAFKA_ADVERTISED_LISTENERS中,OUTSIDE://config-server:9093的config-server服务在你的Docker Compose中不存在,容易导致地址解析混乱。建议简化监听器配置,区分容器内部和外部访问地址:
kafka: image: wurstmeister/kafka container_name: kafka-container ports: - "9092:9092" - "9093:9093" # 新增外部访问端口映射 environment: KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:9093 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,PLAINTEXT_HOST://0.0.0.0:9093 KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_CREATE_TOPICS: "baeldung:1:1" networks: - my-movie-network
PLAINTEXT://kafka:9092供容器内的微服务使用(和你当前的配置一致)PLAINTEXT_HOST://localhost:9093供宿主机或外部服务访问- 同时新增
9093:9093的端口映射,确保外部访问正常
2. 检查Consumer服务的核心配置
确认authentication-service(Consumer)的Spring Kafka配置包含以下关键项:
- 指定消费的Topic:确保
spring.kafka.consumer.topic或@KafkaListener注解中指定的Topic名称为baeldung(和Kafka创建的Topic一致) - Group ID配置:必须设置
spring.kafka.consumer.group-id,Kafka要求Consumer必须属于一个消费组,缺失会导致无法正常消费 - 偏移量重置策略:设置
spring.kafka.consumer.auto-offset-reset=earliest(如果需要消费历史消息)或latest(仅消费新消息),若设为none且无初始偏移量,Consumer会启动失败 - 查看Consumer服务日志,搜索
ConsumerConfig关键字,确认bootstrap-servers、group-id、topic等配置是否正确加载
3. 验证Kafka Topic与消息存储
进入Kafka容器,用命令验证Topic状态和消息:
# 查看所有Topic docker exec -it kafka-container /opt/kafka/bin/kafka-topics.sh --list --bootstrap-server kafka:9092 # 从开头消费baeldung Topic的消息 docker exec -it kafka-container /opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server kafka:9092 --topic baeldung --from-beginning
- 如果控制台能收到消息,说明Kafka本身正常,问题出在Consumer服务的配置
- 如果收不到消息,说明Producer的消息未真正写入Kafka(即使日志显示发送成功,可能是异步发送的确认逻辑问题)
4. 验证容器间网络连通性
进入Consumer容器,测试与Kafka的网络连通性:
# ping Kafka服务,确认域名解析正常 docker exec -it authentication-container ping kafka # 测试9092端口是否可访问 docker exec -it authentication-container telnet kafka 9092
如果连通失败,检查是否所有服务都加入了同一个my-movie-network网络(当前配置已满足),或者是否有防火墙/端口冲突问题
内容的提问来源于stack exchange,提问作者Kollimarla Jagadeep
相关产品推荐
相关产品推荐

