服务启动失败时应先用systemctl确认状态,再用journalctl查完整日志,接着检查配置文件、依赖项及权限、端口、selinux等底层原因。

服务启动失败时,日志是第一手线索。核心思路是:先确认服务状态,再定位对应日志源,最后结合上下文分析错误原因。
查服务当前状态和最近启动记录
用 systemctl 快速确认基础信息:
- systemctl status 服务名 —— 显示服务是否 active、上次启动时间、主进程 PID(如果存在)、以及最近几行 journal 日志摘要
- systemctl is-active 服务名 —— 仅返回 active / inactive / failed,适合脚本判断
- systemctl show 服务名 -p UnitFileState,LoadState,ActiveState —— 查看单元文件是否启用、是否加载成功、当前活跃状态
读取完整的启动日志(journal)
systemd 服务默认日志由 journalctl 管理,启动失败时重点看:
- journalctl -u 服务名 --since "2 minutes ago" —— 查最近两分钟该服务所有日志,包含启动全过程
- journalctl -u 服务名 -n 50 -e —— 显示最近 50 行并跳转到末尾,便于快速定位报错
- journalctl -u 服务名 --no-pager | grep -i "fail\|error\|cannot\|refused\|timeout" —— 快速筛选关键词(注意大小写不敏感)
若服务刚失败过,--since "1 hour ago" 或 --boot(查本次开机以来)也常用。
检查配置文件与依赖项
很多失败源于配置错误或前置条件缺失:
-
systemctl cat 服务名 —— 查看服务单元文件内容,确认
ExecStart路径、用户、工作目录是否正确 - systemctl list-dependencies 服务名 --reverse —— 查哪些服务依赖它;--all 可看完整依赖树,确认 required/wanted 服务是否已启动
- 手动执行
ExecStart命令(注意切换到服务指定的用户和目录),观察是否报错 —— 这能绕过 systemd 封装,暴露真实运行问题 - 检查配置文件语法,如 nginx -t、redis-server --test-conf、mysql --validate-config(各服务命令不同)
关注常见底层原因
以下情况在日志中常表现为“timeout”、“failed to start”、“connection refused”,但根因需深挖:
- 端口被占用:用 ss -tuln | grep :端口号 或 lsof -i :端口 检查
- 权限不足:服务尝试写入目录(如 /var/log/xxx)但用户无权限,或证书文件属主/权限不对(尤其 /etc/ssl/private/ 下)
- SELinux 或 AppArmor 拦截:查看 ausearch -m avc -ts recent(SELinux)或 dmesg | grep -i apparmor
- 磁盘满或 inodes 耗尽:df -h 和 df -i,服务常在初始化时创建临时文件失败










