> 技术文档 > 深入解析 systemd 服务启动失败问题:以 Kafka 服务为例_kafka.service: failed with result \'exit-code

深入解析 systemd 服务启动失败问题:以 Kafka 服务为例_kafka.service: failed with result \'exit-code


个人名片
在这里插入图片描述
🎓作者简介:java领域优质创作者
🌐个人主页:码农阿豪
📞工作室:新空间代码工作室(提供各种软件服务)
💌个人邮箱:[2435024119@qq.com]
📱个人微信:15279484656
🌐个人导航网站:www.forff.top
💡座右铭:总有人要赢。为什么不能是我呢?

  • 专栏导航:

码农阿豪系列专栏导航
面试专栏:收集了java相关高频面试题,面试实战总结🍻🎉🖥️
Spring5系列专栏:整理了Spring5重要知识点与实战演练,有案例可直接使用🚀🔧💻
Redis专栏:Redis从零到一学习分享,经验总结,案例实战💐📝💡
全栈系列专栏:海纳百川有容乃大,可能你想要的东西里面都有🤸🌱🚀

目录

  • 深入解析 systemd 服务启动失败问题:以 Kafka 服务为例
    • 引言
    • 1. 问题描述
    • 2. 可能的原因分析
      • 2.1 主进程崩溃
      • 2.2 systemd 服务配置问题
      • 2.3 资源限制
      • 2.4 依赖服务未就绪
    • 3. 排查步骤
      • 3.1 检查服务日志
      • 3.2 手动运行启动脚本
      • 3.3 检查 systemd 单元文件
      • 3.4 检查资源限制
      • 3.5 检查端口冲突
    • 4. 解决方案
      • 4.1 修复 systemd 单元文件
      • 4.2 修改启动脚本
      • 4.3 检查 Kafka 配置
      • 4.4 重启服务
    • 5. 预防措施
    • 6. 总结

深入解析 systemd 服务启动失败问题:以 Kafka 服务为例

引言

在 Linux 运维和系统管理中,systemd 是最常用的服务管理工具之一。然而,在实际使用过程中,我们经常会遇到服务启动失败的情况,而日志信息往往不够直观。本文将以一个真实的 Kafka 服务启动失败案例为例,详细分析 systemd 服务失败的排查思路、解决方案,并提供优化建议。


1. 问题描述

用户尝试启动 ad-kafka-s 服务,但发现服务在启动后迅速失败。执行 systemctl status 后,关键日志如下:

● ad-kafka-s.service Loaded: loaded (/etc/systemd/system/ad-kafka-s.service; enabled; vendor preset: disabled) Active: failed (Result: exit-code) since Thu 2025-04-24 17:31:28 CST; 791ms ago Process: 4091343 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS) Process: 4098297 ExecStart=/opt/ad_kafka_s/deployer.sh start (code=exited, status=0/SUCCESS) Main PID: 4098300 (code=exited, status=1/FAILURE)Apr 24 17:31:22 kafka-s-index systemd[1]: Starting ad-kafka-s.service...Apr 24 17:31:22 kafka-s-index systemd[1]: Started ad-kafka-s.service.Apr 24 17:31:28 kafka-s-index systemd[1]: ad-kafka-s.service: main process exited, code=exited, status=1/FAILUREApr 24 17:31:28 kafka-s-index systemd[1]: Unit ad-kafka-s.service entered failed state.Apr 24 17:31:28 kafka-s-index systemd[1]: ad-kafka-s.service failed.

从日志可以看出:

  • ExecStart 脚本 /opt/ad_kafka_s/deployer.sh start 返回 0(成功),但主进程(PID 4098300)却以 status=1 失败。
  • 服务在启动后约 6 秒崩溃。

2. 可能的原因分析

2.1 主进程崩溃

  • deployer.sh 可能启动了 Kafka 或其他后台进程,但该进程因配置错误、资源不足或依赖问题而崩溃。
  • 例如,Kafka 可能因 ZooKeeper 连接失败、端口冲突或内存不足而退出。

2.2 systemd 服务配置问题

  • Type 设置不正确:
    • 如果 deployer.sh 启动的是守护进程(如 Kafka),Type 应该设为 forking,否则 systemd 可能误判主进程状态。
  • 缺少 SuccessExitStatus
    • 如果脚本使用非 0 退出码表示成功,需在 systemd 单元文件中声明。

2.3 资源限制

  • 内存不足(OOM Killer 可能杀死进程)。
  • 文件描述符(FD)限制过低。
  • 磁盘空间不足。

2.4 依赖服务未就绪

  • Kafka 依赖 ZooKeeper,如果 ZooKeeper 未启动或连接超时,Kafka 会退出。

3. 排查步骤

3.1 检查服务日志

使用 journalctl 查看详细日志:

journalctl -u ad-kafka-s -n 100 --no-pager

如果 Kafka 有独立日志,检查:

tail -n 100 /opt/ad_kafka_s/logs/server.log

3.2 手动运行启动脚本

/opt/ad_kafka_s/deployer.sh start

观察输出,并检查进程是否存活:

ps aux | grep kafkajps # 查看 Java 进程

3.3 检查 systemd 单元文件

cat /etc/systemd/system/ad-kafka-s.service

典型 Kafka systemd 配置示例:

[Unit]Description=Apache Kafka ServerAfter=network.target zookeeper.service[Service]Type=forkingUser=kafkaGroup=kafkaExecStart=/opt/ad_kafka_s/deployer.sh startExecStop=/opt/ad_kafka_s/deployer.sh stopRestart=on-failureRestartSec=10SuccessExitStatus=0 143LimitNOFILE=65536Environment=\"JAVA_HOME=/usr/lib/jvm/java-11-openjdk\"[Install]WantedBy=multi-user.target

关键点:

  • Type=forking(如果 Kafka 以守护进程运行)。
  • SuccessExitStatus 确保 systemd 正确处理退出码。
  • LimitNOFILE 提高文件描述符限制。

3.4 检查资源限制

# 检查内存free -h# 检查磁盘df -h# 检查 FD 限制ulimit -n

如果 ulimit 过低,可在 systemd 单元文件中增加:

LimitNOFILE=65536

3.5 检查端口冲突

Kafka 默认使用 9092,检查是否被占用:

netstat -tlnp | grep 9092lsof -i :9092

4. 解决方案

4.1 修复 systemd 单元文件

确保 TypeExecStart 正确:

[Service]Type=forkingExecStart=/opt/ad_kafka_s/deployer.sh startExecStop=/opt/ad_kafka_s/deployer.sh stopRestart=on-failure

4.2 修改启动脚本

deployer.sh 示例(确保正确等待子进程):

#!/bin/bashset -e # 出错时退出case \"$1\" instart) echo \"Starting Kafka...\" /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties sleep 5 # 等待 Kafka 启动 ;;stop) echo \"Stopping Kafka...\" /opt/kafka/bin/kafka-server-stop.sh ;;*) echo \"Usage: $0 {start|stop}\" exit 1 ;;esacexit 0

4.3 检查 Kafka 配置

server.properties 关键配置:

broker.id=1listeners=PLAINTEXT://:9092zookeeper.connect=localhost:2181log.dirs=/var/lib/kafka

4.4 重启服务

systemctl daemon-reloadsystemctl start ad-kafka-ssystemctl status ad-kafka-s

5. 预防措施

  • 日志监控:使用 journalctllogrotate 管理日志。
  • 资源限制:调整 systemdLimitNOFILELimitMEMLOCK
  • 健康检查:在脚本中添加进程检查逻辑:
    if ! ps -p $KAFKA_PID > /dev/null; then echo \"Kafka process died!\" exit 1fi

6. 总结

通过本案例,我们学习了:

  1. 如何分析 systemd 服务失败日志。
  2. 排查 Kafka 服务崩溃的常见原因(如配置错误、资源不足)。
  3. 优化 systemd 单元文件和启动脚本。
  4. 预防类似问题的措施(如日志管理、资源限制)。

systemd 服务管理虽然强大,但必须正确配置才能稳定运行。希望本文能帮助你在遇到类似问题时快速定位和解决!🚀


附录:相关命令速查

命令 用途 systemctl status 查看服务状态 journalctl -u 查看服务日志 ps aux | grep 查找进程 netstat -tlnp 检查端口占用 ulimit -n 查看 FD 限制

参考资料

  • systemd.service 官方文档
  • Kafka 官方配置指南