CentOS 上 Kafka 启动失败的定位与修复
一、快速定位步骤
- 查看 systemd 日志与单元状态:执行systemctl status kafka与journalctl -u kafka -n 200 --no-pager,确认失败原因、退出码与起止时间。
- 前台直接启动以获取原始报错:执行**/opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties**(不要后台 nohup),观察控制台输出的首条致命错误。
- 核对依赖与端口:确认Zookeeper已启动且可连接(默认2181),检查9092端口是否被占用(netstat/lsof)。
- 检查关键配置:broker.id唯一、log.dirs目录存在且可写、listeners/advertised.listeners绑定正确、zookeeper.connect地址正确。
- 资源与系统限制:检查内存/磁盘空间、文件描述符限制(ulimit -n),必要时在 systemd 中提升。
- 查阅 Kafka 自身日志:默认在logs/server.log或配置的log.dirs下,优先从日志尾部定位报错关键词。
二、常见原因与对应修复
- Zookeeper 未就绪或连接配置错误
- 现象:日志出现连接 Zookeeper 超时/拒绝。
- 处理:先启动 Zookeeper(systemctl start zookeeper 或前台启动验证),再启动 Kafka;核对zookeeper.connect=host:2181是否可达。
- 日志目录不存在或权限不足
- 现象:启动失败并提示目录不可写。
- 处理:创建目录并赋权,例如:mkdir -p /var/lib/kafka;chown kafka:kafka /var/lib/kafka;chmod 755 /var/lib/kafka;在 server.properties 中设置log.dirs=/var/lib/kafka。
- 端口 9092 被占用或配置冲突
- 现象:BindException/Address already in use。
- 处理:lsof -i :9092 或 netstat -tlnp | grep 9092 找到占用进程并处理;或修改 server.properties 的listeners=PLAINTEXT://:9092为未占用端口。
- 内存不足导致 JVM 无法分配内存
- 现象:Java 报“Cannot allocate memory (errno=12)”。
- 处理:释放内存或降低 Kafka 堆内存(如调整 KAFKA_HEAP_OPTS=“-Xms512m -Xmx512m”),再启动。
- 绑定地址错误(无法指定被请求的地址/UnknownHostException)
- 现象:Socket 绑定到错误 IP 或主机名无法解析。
- 处理:将listeners=PLAINTEXT://0.0.0.0:9092;对外暴露使用advertised.listeners=PLAINTEXT://<服务器IP>:9092;如需本地仅回环可临时用localhost。
- systemd 单元配置不当(Type/ExitCode/资源限制)
- 现象:服务显示 started 但很快 failed,或脚本退出码与主进程不一致。
- 处理:Type 设为forking(若以守护进程方式启动),设置SuccessExitStatus=0 143,提升LimitNOFILE=65536,并在单元中声明User=kafka、Environment=“JAVA_HOME=…”。
三、最小可用配置示例 server.properties
- 基础唯一性与存储
- broker.id=0(集群内唯一)
- log.dirs=/var/lib/kafka
- 网络监听(建议明确双项)
- listeners=PLAINTEXT://0.0.0.0:9092
- advertised.listeners=PLAINTEXT://<服务器IP>:9092
- 依赖地址
- zookeeper.connect=localhost:2181(或 Zookeeper 集群地址)
- 说明:如仅本机调试,可将 advertised.listeners 设为localhost;生产或远程访问务必填写服务器可达的 IP 或 FQDN。
四、systemd 单元文件示例 kafka.service
- 建议路径:/etc/systemd/system/kafka.service
- 示例要点:After 依赖网络与 Zookeeper;Type=forking;正确声明 ExecStart/ExecStop;设置用户与资源限制;声明 JAVA_HOME;使用 Restart 策略
[Unit]
Description=Apache Kafka Server
After=network.target zookeeper.service
[Service]
Type=forking
User=kafka
Group=kafka
ExecStart=/opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
ExecStop=/opt/kafka/bin/kafka-server-stop.sh
Restart=on-failure
RestartSec=10
SuccessExitStatus=0 143
LimitNOFILE=65536
Environment="JAVA_HOME=/usr/lib/jvm/java-11-openjdk"
[Install]
WantedBy=multi-user.target
- 使配置生效:systemctl daemon-reload && systemctl enable --now kafka
五、验证与收尾
- 服务状态与日志:systemctl status kafka;journalctl -u kafka -f;tail -n 200 /opt/kafka/logs/server.log。
- 端口连通:ss -lntp | grep 9092 或 lsof -i :9092;必要时临时关闭防火墙或放行端口做验证(生产环境请按需配置安全组/防火墙)。
- 元数据连通性:使用控制台生产者/消费者测试(如 kafka-console-producer.sh/kafka-console-consumer.sh 指定 –bootstrap-server :9092)。