要让 docker compose 真正支持微服务优雅停机,需协同 stop_grace_period 提供时间窗口、应用监听 sigterm 执行清理、健康检查与反向代理及时摘流,并用 down 命令彻底清理资源;缺一不可。

要让 Docker Compose 真正支持微服务优雅停机,不能只靠配置一个参数——它是一套协同机制:Compose 提供信号与时间窗口,应用代码负责响应,反向代理和健康检查配合摘流,最后才是资源清理。关键不是“能不能停”,而是“停得是否干净、安全、可预期”。
stop_grace_period:给应用留出“收拾行李”的时间
这个字段定义容器收到 SIGTERM 后、被强制 SIGKILL 前的等待上限。默认 10 秒,但业务不同,所需时间差异很大:
- HTTP 服务处理长轮询或大文件上传,建议设为 30–60 秒
- 数据库迁移或批量导出类任务,可能需要 2–5 分钟,需结合
stop_signal和应用层超时控制 - 值设太短,容易触发 137 退出码(SIGKILL),日志里找不到“shutting down”痕迹
- 值设太长,会拖慢滚动更新节奏,尤其在 CI/CD 流水线中影响部署效率
应用必须主动监听 SIGTERM 并执行清理
Compose 不会替你写 shutdown 逻辑。主进程(PID 1)必须捕获信号并完成三件事:
- 立即停止接受新请求(如 Spring Boot 关闭 Actuator 健康端点、Nginx 关闭 listen 指令)
- 等待活跃连接自然结束或主动超时关闭(例如 HTTP server 设置
shutdown上下文超时) - 释放外部资源:关闭数据库连接池、提交/回滚事务、取消定时器、清理临时文件、注销服务发现
常见框架已内置支持:
• Spring Boot 2.3+:启用 server.shutdown=graceful
• Go net/http:调用 server.Shutdown()
• Node.js Express:监听 process.on('SIGTERM') 并关闭 server
配合健康检查与反向代理实现“先摘流、再停机”
优雅停机的前提是上游不再转发新请求。仅靠应用自身响应 SIGTERM 不够,还需基础设施协同:
- 在
docker-compose.yml中配置healthcheck,让负载均衡器(如 Traefik、Nginx)能探测实例状态 - 应用在收到 SIGTERM 后,立即将
/actuator/health返回DOWN,触发反向代理摘除该节点 - 避免“边停边转”:摘流延迟应小于
stop_grace_period,否则仍有新请求打入
资源回收:用 down 而非 stop 清理运行时残留
日常开发调试常用 docker-compose stop,但它只暂停容器,保留网络、卷和状态;生产发布或环境重置应使用 down:
-
docker-compose down:停止容器 + 删除网络 + 保留命名卷(安全,默认行为) -
docker-compose down --volumes:额外清除所有关联命名卷(适合测试环境彻底重置) -
docker-compose down --remove-orphans:清理未在 compose 文件中声明的孤立容器 - 注意依赖顺序:
down默认按依赖逆序停止(先停 app,再停 db),避免应用还在连库时数据库已关
验证是否真正优雅:看日志和退出码
停机后别急着跑下一个命令,花 10 秒确认结果:
- 查退出码:
docker ps -a | grep your-service—— 显示Exited (0)表示正常退出;Exited (137)意味着被 SIGKILL 强杀 - 看末尾日志:
docker logs your-container --tail 20—— 应有 “Graceful shutdown started”、“All connections closed”、“Database pool closed” 类似输出 - 比对时间:从发送 SIGTERM 到容器退出耗时,应略小于
stop_grace_period,过短说明没做清理,过长说明卡在某步(比如未关闭的阻塞 I/O)











