首页/云/Docker 容器速查/stop 慢与超时强杀(-t 宽限期)
容器排障52 条

stop 慢与超时强杀(-t 宽限期)

docker stop 先发 SIGTERM,等待宽限期(默认 10 秒)后发 SIGKILL;应用不处理信号或收尾慢时,数据可能来不及落盘,表现为日志截断与 137。

Docker 容器速查云更新于 2026-10-13

停止慢的两个方向

docker stop 的动作是:给容器主进程发 SIGTERM,等待宽限期(默认 10 秒),仍未退出就发 SIGKILL 强杀。停得慢只有两类原因——应用根本没有处理信号,或者处理了但收尾本身耗时(长事务、批量落盘、向注册中心注销)。走到强杀这一步会跳过收尾逻辑,表现为日志最后几行缺失、退出码 137、数据可能不完整。加大宽限期只是给慢收尾留时间,治本仍在应用侧。

基本信息

默认行为SIGTERM 后等待 10 秒,再发 SIGKILL
调整方式docker stop -t 30;compose 用 stop_grace_period
量化工具time docker stop 容器,实测耗时
判断依据退出码 143 表示自行响应,137 表示被强杀

典型使用场景

  • 发布窗口评估:停机耗时直接决定滚动更新的总时长
  • 数据完整性核查:强杀后检查缓冲数据是否落盘
  • 配置优化:按实测收尾耗时设置合理的宽限期
  • 应用改造验收:确认进程确实收到了信号并执行了清理
  • 批量停机排期:多个实例串行停止,总量要提前估算

测量与调整

测量与调整
# 实测停机耗时
time docker stop web

# 给收尾慢的服务更长宽限期
docker stop -t 30 db

# 检查容器里是不是只有一个主进程在收信号
docker exec web sh -c 'ps -o pid,ppid,comm 2>/dev/null | head -10'

# 确认退出码:143 表示响应了信号,137 表示被强杀
docker inspect -f 'exit={{.State.ExitCode}}' db

停机时间轴

阶段发生的事观察点
0 秒发送 SIGTERM应用日志出现收到信号的记录
宽限期内应用执行收尾连接数下降、缓冲写盘完成
宽限期满发送 SIGKILL 强杀日志可能被截断,收尾逻辑被跳过
容器退出确定退出码143 属于响应后退出,137 属于被强杀
如果容器里主进程是个 shell 包装脚本,信号可能没有转发给真正的业务进程,需要确认 PID 1 的行为是否符合预期。
编排平台下线实例时通常会给一个不短于默认值的等待时间,实际生效值以编排配置为准,容器配置只是其中一层。

易错点

  • 只加大宽限期:不处理信号的进程最终仍会被强杀,先确认信号有没有被接收和转发
  • shell 包装吞掉信号:容器主进程必须是真正的业务进程或正确转发信号,否则停服永远走强杀路径
  • 批量停机不算总时长:宽限期会随实例数叠加,发布窗口要按最坏情况估算
  • 忽略收尾里的外部依赖:注销、加锁释放、通知下游这些动作失败也会拖慢停机,日志要看完整

数据来源与参考

  • Docker 官方 CLI 参考:docker stop -t 与 compose stop_grace_period(docs.docker.com)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌