作业超时与强制终止
超时是任务的兜底机制:没有超时,因网络问题或依赖不可用而挂住的任务会长期占用锁、连接与调度槽位,把后续任务全部阻塞。设计分两层:先给任务设总超时,再给关键步骤设单步超时。终止过程也应分阶段:先发可被捕获的信号让任务保存状态并收尾,等待宽限期后仍不退出才强杀。必须注意的是终止对象是进程组而不是单个进程,只杀父进程会留下仍持锁或仍在写文件的子进程。
基本信息
| 常用参数 | timeout 命令、systemd TimeoutStartSec/TimeoutStopSec、Kubernetes activeDeadlineSeconds 与 terminationGracePeriodSeconds、curl --max-time |
|---|---|
| 终止信号 | SIGTERM 可被捕获用于收尾,SIGKILL 不可捕获,用于强杀 |
| 关键点 | 终止整个进程组;超时必须产生告警而不是静默处理 |
| 平台差异 | Linux 用信号,Windows 服务管理器用停止超时,容器由运行时控制 |
典型使用场景
- 命令可能因网络问题永久挂住,需要硬性时限
- 任务持锁导致后续任务全部被阻塞
- 服务停止时需要在宽限期内完成在途请求
- 批量执行中个别主机无响应,不能拖住整批
- 容器内进程不响应停止信号,需要运行时终止兜底
超时与终止写法
超时与终止写法
timeout --signal=TERM --kill-after=30 600 /opt/bin/job.sh # 先 TERM,30 秒后强杀
set -m # 启用作业控制便于管理进程组
kill -TERM -"$pgid" # 向整个进程组发信号
systemctl show -p TimeoutStopUSec app.service # 查看生效的停止超时
ps -eo pid,ppid,stat,cmd | grep -w defunct # 检查残留的僵死或孤儿进程
kubectl describe pod job-x | grep -i deadline # 确认是否因超时被终止超时参数与平台
| 参数 | 所属平台 | 含义 |
|---|---|---|
| timeout --kill-after | Linux coreutils | 宽限期结束后强制终止 |
| TimeoutStopSec | systemd | 停止服务时允许的收尾时间 |
| terminationGracePeriodSeconds | Kubernetes | 容器终止宽限期 |
| activeDeadlineSeconds | Kubernetes | 作业总运行时限 |
| --max-time | curl | 整个请求允许的最长耗时 |
只终止父进程往往不够:脚本派生的子进程可能继续持锁或继续写文件。正确做法是把进程组一并终止,或让任务在收到终止信号时自行清理子进程。
强杀发生在写文件或写数据库的中途,可能留下半截文件或损坏的状态标记。启动阶段应检查并清理上次残留,而不能假设每次都能优雅退出。