排查 systemd 服务失败需四步:先看 systemctl status 确认 Active 状态、ExecStart 命令和 status=退出码;再用 journalctl -u -n 50 -e 查真实错误日志;接着验证配置语法并手动模拟启动;最后检查依赖服务、环境变量及工作目录。

先看 systemctl status 确认失败状态和退出码
这是排查起点,不是走形式。重点盯三处:Active: 行是否为 failed;Process: 行里 ExecStart= 后的完整命令;以及 status= 后的数字(比如 status=1/FAILURE)。这个退出码本身没意义,但结合日志就能定位是配置错、权限错,还是进程一启动就崩了。
- 如果显示
inactive (dead)且没报错,大概率是服务压根没被手动启过,别急着查日志 -
status=203/EXEC常见于路径写错或二进制不存在(比如把/usr/bin/nginx写成/usr/sbin/nginx) -
status=217/USER多因User=配置项指定的用户不存在,或家目录不可访问
用 journalctl -u 服务名.service -n 50 -e 挖真实错误
日志里藏了所有“为什么失败”。加 -n 50 是防刷屏,-e 直接跳到末尾——最新一行往往就是致命错误。常见线索有:
-
Permission denied:不是单纯文件权限问题,要顺藤摸瓜查 SELinux 上下文(ls -Z)、AppArmor profile 或 systemd 的ProtectSystem=限制 -
Address already in use:端口被占,但注意netstat -tulpn | grep :80可能看不到被 systemd socket 激活的服务,得看ss -tlnp -
Failed to load environment files:检查/etc/sysconfig/服务名或 service 文件里EnvironmentFile=指向的路径是否存在、是否可读
验证配置语法 + 手动模拟启动
很多服务自带校验命令,不跑等于白配。而且配置文件权限不对,服务会静默忽略——比如 MySQL 发现 /etc/my.cnf 权限是 664 就直接跳过,连日志都不记。
- Nginx:
nginx -t,它会告诉你哪行配置错、哪个 include 路径不存在 - Redis:
redis-server --test-memory /etc/redis/redis.conf,还能顺便测内存 - 手动执行:
sudo -u www-data /usr/sbin/nginx -g 'daemon off;',能暴露环境变量缺失、工作目录不可写、动态库找不到等 systemd 日志里不显示的细节
检查依赖服务和启动时机
systemd 不是线性启动,而是按依赖图调度。一个服务 failed,可能只是上游没起来。别只盯着报错服务本身。
- 运行
systemctl list-dependencies --reverse 服务名.service,看它依赖哪些 unit;再用systemctl status逐个查这些依赖的状态 - 典型冲突:NetworkManager 和 systemd-networkd 同时启用,其中一个被
mask但没停干净,导致networking.service卡在activating - 时间敏感服务(如 NTP、证书自动续期)若在
After=multi-user.target启动,可能因系统时间未同步而失败,得改用After=time-sync.target
最常被跳过的其实是环境变量和工作目录——systemd 的默认环境极简,$PATH 可能不含 /usr/local/bin,WorkingDirectory= 不设的话,脚本里的相对路径全失效。这些点不显眼,但修起来最快。










