Docker不支持毫秒级自愈,实际最短恢复窗口为1–3秒;应按服务类型选用restart policy(无状态用on-failure:5,守护进程用unless-stopped),配置真实业务健康检查,并通过Docker Compose的unhealthy重启策略实现闭环自愈。
docker 本身不支持“毫秒级自愈”,重启和重建容器必然存在延迟——从进程退出、状态检测、镜像拉取(如需)、初始化网络、挂载卷到应用真正就绪,通常需要数百毫秒至数秒。所谓“毫秒级”是常见误解,实际可控的最短恢复窗口在 1–3 秒左右,且依赖精细配置与轻量环境。
关键不是堆参数,而是避开陷阱、选对策略、让健康检查真正起作用。
Restart Policy 选型要匹配服务类型
不同策略响应逻辑不同,错误选择反而拖慢恢复或掩盖问题:
-
on-failure:5:适合 Web API、任务型服务。只在崩溃(非零退出)时重试,最多 5 次,防止死循环重启;不会因 OOM 或信号终止误触发,更安全 -
unless-stopped:推荐用于 Nginx、Redis 等守护进程。宿主机重启后自动拉起,但docker stop后不再强启,运维可控 -
always要慎用:手动docker stop后会立刻重启,调试困难;OOM 被杀后可能反复拉起,引发资源雪崩
✅ 生产建议:无状态服务用
on-failure:5,长期守护服务用unless-stopped
健康检查必须真实反映业务可用性
仅靠进程存活(PID 1 是否在)无法识别“假活”:Node.js 进程卡死、端口监听但不响应请求,on-failure 完全无效。
在 Dockerfile 中加入业务探针:
HEALTHCHECK \ --interval=20s \ --timeout=3s \ --start-period=40s \ --retries=3 \ CMD curl -f http://localhost:3000/health || exit 1
-
--start-period=40s:给冷启动留足时间,避免刚起就误判 -
--retries=3:连续失败 3 次才标为unhealthy,抗网络抖动 -
/health必须是真实业务端点(返回 200 + JSON{ "status": "ok" }),不能是curl localhost:3000这类空响应探测
Docker Compose 驱动健康态重启闭环
Docker 自身的健康检查不会自动重启容器,必须由编排层联动。Docker Compose v2.2+ 支持 restart_policy.condition: unhealthy:
services:
api:
image: my-api:v1
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 20s
timeout: 5s
retries: 3
start_period: 40s
restart_policy:
condition: unhealthy
delay: 5s
max_attempts: 3
这样当健康检查连续失败,Compose 会在约 5–8 秒内停止旧容器、启动新实例——这是目前单机 Docker 下最接近“快速自愈”的实践。
别忘了 Docker 守护进程自身要开机自启
再好的策略也依赖 Docker 先跑起来:
sudo systemctl enable docker sudo systemctl is-enabled docker # 应返回 enabled
否则 unless-stopped 和 always 在宿主机重启后根本不会生效。
不复杂但容易忽略











