服务器重启后,业务服务常卡在 activating,随后变成 failed;日志只有 timeout,现场却涉及网络、挂载、用户和内存上限。依赖未满足会阻塞后续单元,权限沙箱会终止进程,超时还会掩盖资源问题。排查应先还原 systemd 依赖图,再用日志、退出码和资源事件交叉判断,不能靠反复重启。
如果你正在选机器,或者想先把线路和配置跑通再谈长期方案,可以先看看这几家的线路说明和技术参数:iwebfusion(全球云服务器),先看清带宽线路、流量策略和退款条款,再决定要不要迁。
一、沿 systemd 依赖图寻找真正的阻塞点
先用 systemctl status 服务名 找失败单元,再用 systemctl list-dependencies --failed 缩小范围,并查看 After、Requires、Wants、ExecStartPre,还原服务启动顺序。After 只规定先后,不保证前序就绪;Requires 缺失会导致失败,Wants 通常不阻止启动,BindsTo 更严格。网络、挂载和路径单元还须真正处于 active 状态。

若 A 等待 B,而 B 的脚本或磁盘条件失败,A 可能根本不会执行。systemd-analyze critical-chain 服务名 可显示关键链,再用 journalctl -u B -b 查首个错误。应先修复依赖末端,不要用追加 After 或重复 restart 掩盖根因。
二、从沙箱、启动超时与资源限制核对退出原因
服务本体启动后,用 journalctl -u 服务名 -b 查看退出码,重点关注 203/EXEC、200/CHDIR、226/NAMESPACE、13/PERM,分别对应执行路径、工作目录、命名空间或权限问题。核对 User、Group、WorkingDirectory 与 ProtectSystem、ProtectHome、PrivateTmp 等限制。多机检索可用 ServLlama 汇集 journald 日志片段,但仍以主机原始记录为准。
进程未退出却一直处于 activating 时,要区分启动超时与业务就绪。TimeoutStartUSec 限制启动阶段,ExecStartPre 另有时限;Type=simple 在主进程创建后即为 active,并不代表能接收流量;Type=notify 则要等待 READY=1。若就绪通知接近资源峰值,应继续查资源,而非直接放大超时。

用 systemctl show 服务名 -p MemoryMax -p TasksMax -p LimitNOFILE 查看限制,结合 cgroup memory.events 与 journald 的 oom 事件判断。OOM 应先核实峰值、泄漏和并发;任务数及文件描述符问题也要分别处理。权限应精确添加可写目录或能力,避免 chmod 777;只延长启动超时不能替代修复依赖和资源。
从依赖图找到真正的阻塞单元
服务进入 failed 状态后,先别把结论停在服务本身。systemd 会把各单元合并成一张systemd依赖图:Requires 表示强依赖,Wants 表示弱依赖,After、Before 描述服务启动顺序,ExecStartPre 与 ExecStartPost 则是主进程前后的钩子。依赖图要同时看“谁需要谁”和“谁应排在谁之前”;仅有 After 并不代表依赖已经健康。可用 systemctl list-dependencies 展开上下游,用 systemctl show 核对最终生效值,再用 systemd-analyze verify 排除循环依赖和 unit 语法错误。前置单元失败时,后续服务即使程序正常,也会被连带终止。
最容易踩的坑是把排序当成就绪。After=network.target 只说明 network.target 排在前面,不代表网卡地址、默认路由、DNS 或时间同步已经可用;反过来,随意添加 Requires 会把原本可选的依赖变成硬性故障,依赖服务偶发失败,主服务也会被拖停。更稳妥的方案是给程序加入有限重试,并设置 Restart=on-failure、合理的 RestartSec 和启动频率上限,而不是无限重启掩盖根因。
遇到沙箱权限拒绝,要先定位是谁在拒绝。systemd 沙箱中的 ProtectSystem、ProtectHome、PrivateTmp、NoNewPrivileges 会改变服务可见目录、临时目录、用户身份和能力集;SELinux、AppArmor 还可能在 systemd 之外继续拦截。systemctl cat 只能看到磁盘上的 unit,systemctl show 才能看到最终属性及覆盖来源。排查时应按 unit 指定的用户复现路径搜索、文件读写和端口绑定,并核对目录执行位、父目录搜索位、目标文件属主与权限。管理员在终端执行成功,不代表服务上下文同样拥有权限。

用日志、权限与超时完成闭环
启动超时也要按阶段定位。TimeoutStartSec 通常约束整个启动过程,ExecStartPre 等前置命令可能有自己的超时;数据库迁移、证书签发、DNS 探测和远程挂载都可能拖慢启动。journald日志应按本次启动范围读取,例如 journalctl -u 服务名 -b,再用 -o short-precise 对齐时间戳;systemctl status 只能给出摘要,进程是否存活、前一条日志停在哪里,往往更能区分“慢”“阻塞”和“已退出”。
① 用 systemctl cat 核对 User、WorkingDirectory、EnvironmentFile、路径大小写和缺失配置。
② 用 list-dependencies 与 systemd-analyze verify 检查依赖缺失、循环和排序。
③ 按 unit 用户复现权限,检查端口占用及 SELinux、AppArmor 拒绝记录。
④ 依据最后一条 journald 日志锁定阶段,只调整对应 TimeoutStartSec 或命令超时。
⑤ 修改后依次执行 systemctl daemon-reload、systemctl restart 服务名,再读取 journalctl -u 服务名 -b 复核。一次只改一项,并保留修改前后的日志。
按“依赖图 → 生效配置 → 权限边界 → 阶段日志 → 重启验证”的顺序收口,才能把 unit 配置错误、沙箱策略冲突和程序自身故障分开;这样得到的结论既可复现,也能回滚。


喜欢
顶
难过
囧
围观
无聊





