停止信号与超时是什么
docker stop 先向容器主进程发信号,等待一段时间后再强杀。默认发 SIGTERM、等 10 秒;用 --stop-signal 与 --stop-timeout 可以按应用实际支持的信号与清理耗时定制,让服务有机会摘流量、写完数据再退出。
基本信息
| 默认行为 | 发 SIGTERM,超过宽限时间后 SIGKILL |
|---|---|
| 语法 | --stop-signal SIGQUIT、--stop-timeout 30(秒) |
| 单次覆盖 | docker stop -t 30 容器名 |
| Compose 对应 | stop_signal、stop_grace_period 两个字段 |
| 强杀信号 | SIGKILL(9) 不给进程清理机会,只能作为兜底 |
典型使用场景
- 需要优雅退出的 Web 服务:处理完在途请求再退出,避免连接被硬断
- 消息消费类服务:保证正在处理的消息提交完成,减少重复消费
- 有长事务或缓存的数据库类服务:留足落盘时间,降低文件损坏风险
- nginx 这类有专门关闭信号的程序:设成对应信号实现平滑退出
- 排查停止耗时长或数据偶发损坏:核对信号与宽限时间是否符合应用实现
- 批量滚动重启前统一停止行为,避免个别实例被强杀制造脏数据
示例
示例
docker run -d --name web \
--stop-signal SIGQUIT --stop-timeout 30 \
nginx:1.27-alpine
docker stop -t 30 web # 本次停止把宽限放宽到 30 秒
docker stop web # 使用容器自身设定的超时值
docker kill --signal=SIGUSR1 web # 需要转发其他信号时用 kill --signal停止过程的几个阶段
| 阶段 | 默认行为 | 可调项 |
|---|---|---|
| 发送信号 | 向容器主进程发 SIGTERM | --stop-signal |
| 等待退出 | 默认 10 秒 | --stop-timeout 或 stop -t |
| 超时处理 | 发 SIGKILL 强制杀死 | 不可豁免,只能调整宽限时间 |
| 多进程容器 | 信号只发给 PID 1 | PID 1 要负责转发,可配合 --init |
| 进程忽略信号 | 时间一到照样被强杀 | 需要在应用侧实现优雅退出 |
nginx 官方镜像的停止信号是 SIGQUIT,覆盖成其他信号会影响连接是否平滑关闭,动手前先确认程序实际支持的信号。
信号只发给容器里的 PID 1:主进程若是 shell 脚本且不转发信号,应用根本收不到,这时需要 --init 与脚本配合处理。
compose 里对应 stop_signal 与 stop_grace_period 两个字段,语义与命令行参数一致,从命令行迁到文件时按同样思路配置即可。