排查 systemd 服务失败应先查 journalctl 日志找真实错误,再核对服务定义合法性,最后手动模拟启动验证权限、路径和配置。

直接看日志,别只盯着 systemctl start 那句“failed”提示。systemd 的报错信息本身不带具体原因,它只是告诉你“进程退出了”,真正的错误藏在运行时输出里。
第一步:查服务当前状态和简要线索
运行:systemctl status 服务名.service
重点关注三处:
- Active 行是否为 failed;
- Main PID 是否为空或显示已退出;
- 最后几行日志里有没有关键词,比如 Permission denied、No such file or directory、Failed to load configuration。
第二步:翻完整日志,找真实错误输出
执行:journalctl -u 服务名.service --since "1 hour ago" -n 50 --no-pager
这会拉出最近一小时该服务的日志,最多50行,去掉分页干扰。重点扫描:
- 启动过程中第一行报错(不是 systemd 自己的提示,而是服务程序自己打印的);
- 出现 error、fail、cannot、missing 的行;
- 段错误(segmentation fault)、库缺失(libxxx.so: cannot open shared object file)、配置语法错误等。
第三步:检查服务定义是否合法
运行:systemctl cat 服务名.service
确认以下内容无误:
- ExecStart 路径存在且可执行:ls -l /路径/到/二进制;
- 若指定了 User 或 Group,该用户必须真实存在;
- Type 匹配实际行为(例如脚本用 Type=simple,后台守护进程可能需 Type=forking);
- 没有拼写错误,比如把 EnvironmentFile 写成 EnviromentFile。
第四步:手动模拟启动,绕过 systemd 封装
按 unit 文件里的设置,切换用户、设置环境变量,再执行 ExecStart 命令。例如:sudo -u www-data /usr/bin/php-fpm --f /etc/php/8.2/fpm/php-fpm.conf -t
这样做能暴露 systemd 日志里看不到的问题:
- 当前用户对配置文件或 socket 目录无读写权限;
- 工作目录不存在或不可访问;
- 环境变量缺失(如 PATH 不含所需命令);
- 配置校验失败(很多服务支持 -t 参数测试语法)。


















