应使用 systemctl list-units --state=failed --type=service 准确定位失败服务,再通过 systemctl status --no-pager -l 查看详细状态及日志,结合 journalctl -u 和 dmesg 深挖 oom、权限、资源限制等根因,最后按残余类型(failed/masked/not-found/脱管进程)分类清洗。

直接运行 systemctl --failed --all 并不能“全面检索并清洗”残余单元——这个命令本身只列出当前被 systemd 标记为 failed 状态的已加载单元,且不区分失败原因,更不会自动识别“资源耗尽”或“权限配置不当”这类深层根因。
先准确识别真正失败的服务
用标准命令定位明确失败项:
-
systemctl list-units --state=failed --type=service—— 专注服务类型,排除挂载、套接字等干扰项 - 加
--no-pager -l查看完整状态:systemctl status 服务名.service --no-pager -l,重点确认 Active 行是否为failed (result: exit-code)或failed (result: signal) - 若输出为空,不代表无问题:有些服务启动即退出但未被标记 failed(如 ExecStart 命令前台执行失败后静默退出),需结合日志主动排查
从日志中提取资源与权限类线索
失败本身是表象,journalctl 才暴露根因:
- 查 OOM 杀死痕迹:
dmesg -T | grep -i "killed process" | tail -10。匹配到进程名 + “total-vm”“anon-rss”字段,基本可判定内存耗尽 - 查权限拒绝类错误:
journalctl -u 服务名.service --since "1 hour ago" | grep -i "permission denied\|operation not permitted\|no such file or directory"。特别注意路径不存在(如 WorkingDirectory)、文件不可执行(ExecStart 脚本无 x 权限)、用户无权访问日志/临时目录等情况 - 查资源限制触发:
systemctl show 服务名.service | grep -E "(MemoryLimit|LimitNOFILE|TasksMax|OOMScoreAdjust)"。若 MemoryLimit 显式设为较低值,或 LimitNOFILE 远低于应用所需(如 Nginx worker 需万级 fd),即属配置不当
清洗“残余单元”需分清类型,不能一删了之
所谓“残余”,常见三类,处理方式完全不同:
-
已失败但 unit 文件仍存在:用
systemctl reset-failed 服务名.service清除失败标记;若确认不再需要,再systemctl disable 服务名.service && rm /etc/systemd/system/服务名.service -
loaded but not-found:执行
systemctl list-units --state=not-found列出。这些是引用残留,非真实服务。检查systemctl show 服务名.service | grep FragmentPath,路径不存在即可忽略,无需手动删除 -
脱管进程(PID 已丢失):运行
systemctl show 服务名.service --property=MainPID,若返回 0 或无效 PID,说明 systemd 失去控制。此时应先systemctl stop 服务名.service,再kill -9 $(pgrep -f "关键词")清理残留进程,最后检查 /var/run/ 或 /tmp/ 下对应 pid/socket 文件并手动删除
避免误操作的关键提醒
不要用 systemctl --failed --all 的输出直接批量清理:
- 该命令会混入 inactive、not-found、masked 等非失败项,语义不纯
- 统信UOS、CentOS Stream 等系统中,部分服务(如 bluetooth、ModemManager)可能因硬件缺失短暂 failed,属正常行为
- mask 操作不可逆(需 unmask 才能恢复),禁用开机自启请用
disable,而非mask - 所有配置修改后,必须
systemctl daemon-reload才生效,否则清洗动作可能作用于旧定义











