systemd服务停止超时被强制杀死,本质是服务未在TimeoutStopSec内干净退出,systemd被迫用SIGKILL终止整个cgroup;排查重点是“为什么停不掉”,需检查KillMode、进程树残留、阻塞型依赖及资源释放卡点。

systemd 服务停止时超时被强制杀死,本质是 服务未在 TimeoutStopSec 规定时间内干净退出,systemd 被迫发送 SIGKILL 终止整个 cgroup。排查重点不是“为什么没停”,而是“为什么停不掉”——卡点常在子进程、资源释放或同步等待上。
看停止过程的真实行为,别只信 status
systemctl status 只显示最终快照,容易漏掉卡住瞬间。要抓实时动作:
- 执行
sudo systemctl stop your-service.service && sudo journalctl -u your-service.service -f,观察停止命令发出后头几秒是否有日志输出(如 “Stopping…”、“Waiting for workers…”) - 停止失败后立刻运行
journalctl -u your-service.service --all --no-pager,--all能捞出被截断、未刷盘或 pre-stop 阶段的日志,常含关键线索 - 若服务极快退出又卡住,用
strace -f -p $(systemctl show your-service.service -p MainPID --value)实时跟踪主进程系统调用,看是否卡在wait4、epoll_wait或close
查 KillMode 和进程树结构,确认谁真被杀
systemd 默认用 KillMode=control-group,会杀整个 cgroup 下所有进程。但若子进程脱离控制或僵死,就会拖慢停止:
- 运行
systemctl show your-service.service | grep KillMode确认当前模式 - 查进程归属:
systemd-cgls /system.slice/your-service.service,看是否有子进程未退出、或已变成孤儿(PPID ≠ 主进程 PID) - 若发现残留进程,用
ps --ppid $(systemctl show -p MainPID --value your-service.service)检查父子关系;再用cat /proc/PID/status | grep -E "(State|PPid)"判定是否僵死
定位阻塞型依赖或资源释放卡点
服务本身逻辑没问题,但卡在等外部条件释放:
- 检查依赖链:
systemctl list-dependencies --reverse your-service.service,特别关注network.target、remote-fs.target、umount类单元是否也卡在 stopping 状态 - 查内核级阻塞:
dmesg -T | grep -i "nf_conntrack\|device-mapper\|nfs: server",出现table full, dropping packet或killing queued I/O表明连接跟踪或块设备释放失败,后续服务停止必超时 - 验证文件锁与端口:
lsof -i -P -n -sTCP:LISTEN | grep your-service和lsof +D /path/it/uses,确认没有残留句柄阻止 clean shutdown
调大超时前先验证是否真慢,还是配置错
盲目加 TimeoutStopSec 可能掩盖真实问题:
- 查当前值:
systemctl show your-service.service | grep TimeoutStopSec(默认通常为 90s) - 手动模拟停止流程:以服务用户身份执行
ExecStop命令(若有),或直接发信号kill -TERM $(MainPID),计时看是否真需超过 90 秒 - 若确认需更久,用覆盖方式安全调整:
sudo systemctl edit your-service.service,填入:
[Service]
TimeoutStopSec=180
保存后执行sudo systemctl daemon-reload


















