用 journalctl 快速定位服务启动失败:从 unit 状态到日志过滤的排查顺序
服务起不来时,先别急着改配置或反复重启。systemd 的 unit 状态和 journal 日志已经把大部分线索写清楚了,按固定顺序查,往往几分钟就能定位到是配置错、端口被占、权限不足,还是依赖没起来。
第一步:先看 unit 状态,别只看“启动失败”四个字
systemctl status nginx
systemctl is-failed nginx
systemctl is-enabled nginx
status 重点看三处:Active 是 failed 还是 inactive,Main PID 和退出码,以及最后十几行日志摘要。is-failed 返回 failed 说明这次启动确实失败了,而不是服务根本没被拉起。is-enabled 则区分“开机没自启”和“启动时报错”,这两类问题排查方向完全不同。
如果状态是 failed (Result: exit-code),先记下退出码;如果是 failed (Result: timeout),多半是启动过程卡住了,比如等网络、等某个依赖、等锁文件释放。
第二步:用 journalctl 只看这个服务,别翻全系统日志
journalctl -u nginx --no-pager
journalctl -u nginx -p err --no-pager
journalctl -u nginx --since "2026-10-30 09:00" --no-pager
journalctl -u nginx -n 100 --no-pager
-u 只过滤指定 unit,--no-pager 避免 less 拦截输出,适合直接复制到工单或终端里比对。-p err 只看 err 及以上级别,先排除 info 和 notice 的噪音;如果 err 里没有线索,再放宽到 -p warning 或不加级别。--since 一定要对齐故障时间,否则很容易把几天前的旧报错当成当前原因。-n 100 适合服务刚失败、只想看最近一次启动的尾巴。
第三步:按报错类型分流,不要逐行猜
1. 配置语法错:先校验,再重启
日志里出现 failed to load configuration、unknown directive、directive is not allowed here,基本是配置文件写错了。对 Nginx 用 nginx -t,对其他服务先看它自带的 --test 或 configtest,改完再重启,不要在没校验的情况下反复 restart。
2. 端口被占:先找占用者,再决定改端口还是停旧进程
Address already in use、bind() failed 出现时,用 ss -tlnp | grep 80 看看到底是谁占着端口。常见情况是旧进程没退出、另一个服务抢了端口,或者上次启动的残留进程还在。先确认占用者是不是自己要的服务,再决定杀进程还是改监听端口,不要直接把端口换掉掩盖问题。
3. 权限或路径错:看清是读不到,还是写不进
Permission denied、No such file or directory、cannot open 这类报错,先用 ls -l 确认文件和目录是否存在、属主和权限对不对,再看 systemd 的 User=、WorkingDirectory=、ExecStart= 路径是否写错。服务以非 root 用户运行时,经常是能读配置却写不了日志或 PID 文件,报错位置不同,修法也不同。
4. 依赖没起来:看启动顺序,别只盯着本服务
Dependency failed、start request repeated too quickly、Job for xxx.service failed 说明问题可能不在本服务。先看 systemctl list-dependencies nginx --all,再看依赖服务的 status 和日志;repeated too quickly 还要查 StartLimitIntervalSec 和重启策略,避免服务在死循环重启里把日志刷爆。
一个可复用的排查顺序
systemctl status <服务名>:确认是 failed、inactive,还是根本没启动。journalctl -u <服务名> --since <故障时间> --no-pager:锁定本次故障的日志。journalctl -u <服务名> -p err --no-pager:先看错误级别,缩小范围。- 按报错分流:配置校验、端口占用、权限路径、依赖服务,四选一。
- 改一处、验一处:改完用
systemctl restart后立刻再看一次status和最新日志,确认报错消失再收尾。
容易踩的三个坑
- 只看
systemctl status尾部十行就下结论:它只是摘要,真正原因经常在 journal 里更早的位置。 - 不加
--since翻旧日志:把上周的报错当成今天的原因,改错方向。 - 反复重启掩盖问题:
restart能暂时拉起服务,不等于修好了配置或端口冲突,下次重启还会失败。
按“状态—日志—分流—验证”这个顺序走,服务启动失败就不再是玄学,而是一条可以复现的排查链。
- 点赞
- 收藏
- 关注作者
评论(0)