用 docker-compose 三步拉起本地 kafka 环境:①安装 docker 和 docker-compose v2.15+;②编写 docker-compose.yml 启用 kraft 模式(无需 zookeeper),配置 advertised.listeners=plaintext://localhost:9092;③验证连通性并规范客户端 bootstrap.servers 配置。

用 docker-compose 三步拉起本地 Kafka 环境
别折腾 ZooKeeper 单独部署,Kafka 3.3+ 已默认内置 KRaft 模式,ZooKeeper 不再必需。本地开发直接用 docker-compose 启动最稳。
- 确保已安装 Docker 和
docker-compose(v2.15+) - 新建
docker-compose.yml,核心只配kafka和schema-registry(可选),不用写zookeeper服务 - 镜像优先选
confluentinc/cp-kafka:7.4.0或apache/kafka:3.7.0,避免用latest——它可能突然切到不兼容的主版本
示例最小配置片段:
services:
kafka:
image: apache/kafka:3.7.0
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka:9093"
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
ports:
- "9092:9092"
KafkaConsumer 连不上 localhost?检查 advertised.listeners 配置
Java 客户端连不上,90% 是因为 advertised.listeners 写成 kafka:9092 或 0.0.0.0:9092,导致消费者拿到错误 host 去连接。
- 本地开发务必设为
PLAINTEXT://localhost:9092,让 Java 客户端解析后直连本机 - 如果用 WSL2 或 Docker Desktop for Mac,
localhost在容器内不指向宿主机,此时要改用宿主机真实 IP(如192.168.x.x),并确认防火墙放行 9092 - 启动后执行
docker exec -it <container> kafka-topics.sh --bootstrap-server localhost:9092 --list</container>能列出 topic,才说明服务端监听和广播都正常
Java 代码里 bootstrap.servers 别写死,用配置中心或 profile 隔离
硬编码 "localhost:9092" 在测试环境能跑,一上 CI/CD 就炸——生产环境 broker 地址是集群地址,还带 SASL 认证。
立即学习“Java免费学习笔记(深入)”;
- Spring Boot 用户:把
spring.kafka.bootstrap-servers放进application-dev.yml和application-prod.yml,通过--spring.profiles.active=prod切换 - 纯 Java(非 Spring):用
System.getProperty("kafka.bootstrap")或读取config.properties文件,别在代码里 new Properties().put("bootstrap.servers", "...") - 注意
bootstrap.servers只需填 1–2 个 broker 地址即可,不是全量列表;填太多反而增加初始化延迟
Consumer 消费不到消息?先查 group.id 和 auto.offset.reset
新 Consumer 第一次运行没日志、没报错、但就是收不到消息,基本是 offset 行为没对齐。
-
group.id相同的 Consumer 共享 offset,如果之前跑过并 commit 过 offset,新启动会从上次位置继续——可能已是 EOF - 临时调试时加配置:
props.put("auto.offset.reset", "earliest"),强制从头读;但上线前必须删掉,否则会重复消费历史数据 - 用命令行验证:
kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --group debug-group --from-beginning,看是否真有数据 - 注意:Spring Kafka 的
@KafkaListener默认auto-offset-reset=latest,和原生客户端默认值不同,容易误判
真正麻烦的是跨网络、跨权限、跨协议的集成场景——比如对接云上 MSK 或 Confluent Cloud,SSL 和 SASL 配置项多出一倍,但本地环境调通这四步,才是后续所有扩展的前提。











