docker 容器终止时都做了什么?怎么优雅退出?
docker container stop
的“优雅退出”并不是等到“没有请求流量”才退出,而是通过 信号机制 来实现的。
🧠 工作原理
-
当你执行
docker container stop <容器>
时:- Docker 会先向容器的 主进程(PID 1) 发送 SIGTERM 信号。
- 这相当于“礼貌地通知”应用:请准备退出。
-
应用如果正确处理了 SIGTERM:
- 会停止接收新请求
- 完成正在处理的请求
- 关闭数据库连接、文件句柄等资源
- 然后正常退出
-
Docker 默认会等待 10 秒(可用
-t
参数调整)。- 如果进程在这段时间内退出 → 就是“优雅退出”。
- 如果超时还没退出 → Docker 会发送 SIGKILL,强制终止。
📦 举个例子
-
Web 服务容器:收到 SIGTERM 后,应用可以先停止监听端口,不再接受新请求,同时把正在处理的请求完成,然后退出。
比如:Java 应用(Spring Boot 等)
默认行为:JVM 会响应 SIGTERM,触发 Runtime.addShutdownHook。
最佳实践:
在 @PreDestroy 或 DisposableBean.destroy() 中释放资源。
关闭数据库连接池、消息队列消费者。
确保线程池 shutdown() 并等待任务完成。 -
数据库容器:会在退出前把缓存数据刷到磁盘,避免数据丢失。
✅ 总结
- 优雅退出 ≠ 等待没有流量
- 优雅退出 = 收到 SIGTERM → 应用自己清理资源并退出
- 如果应用没处理 SIGTERM,Docker 会在超时后用 SIGKILL 强制杀掉进程。