最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Docker Compose 如何处理容器内部的异常中断
时间:2026-08-31 20:08:48 编辑:袖梨 来源:一聚教程网
Docker Compose不感知异常类型,仅依据容器主进程退出码和restart策略决定是否重启:always无条件重启,unless-stopped排除手动停止,on-failure仅非零退出码重启(可限次),no不重启;需配合healthcheck识别假活,并通过logs和inspect查退出码(如137为OOM)定位根因。
Docker Compose 本身不直接监控或干预容器内部的异常中断(比如应用 panic、段错误、空指针崩溃等),它依赖 Docker 引擎提供的 重启策略(restart policy) 来响应容器进程退出这一结果。换句话说,Compose 不“感知”异常类型,只关心容器主进程是否退出,以及退出码是否符合预设条件。
重启策略决定是否拉起新实例
当容器内应用崩溃导致主进程退出时,Docker 守护进程会捕获退出状态,并根据你配置的 restart 字段决定是否重启容器:
- always:不管退出码是 0 还是非 0,立即重启——适合必须常驻的服务,如 Nginx、Redis
-
unless-stopped:同
always,但若你手动执行过docker stop,则不再自动拉起——生产环境最常用 -
on-failure[:max]:仅当退出码非 0 时重启,可限制最多重试次数(如
on-failure:3)——避免无限崩溃重启循环 - no:默认行为,退出后不重启——适用于调试、一次性任务
需要配合健康检查提升判断精度
单纯靠进程退出码有局限:有些应用进程没死,但已卡死或无法响应请求(例如死锁、内存泄漏后假活)。这时单靠 restart 策略无法触发恢复。建议在 Compose 中启用 healthcheck:
- 定义周期性探测(如
curl -f http://localhost/health || exit 1) - 设置超时、重试间隔和失败阈值
- 当健康检查连续失败达到阈值,Docker 会将容器状态标记为
unhealthy - 注意:健康状态本身不会触发重启,但可配合外部工具(如 watchtower、自定义脚本)或上层编排系统(如 Swarm、K8s)做进一步动作
日志与退出码是排查关键线索
容器异常中断后,第一时间应查看日志确认根本原因:
-
docker compose logs -f <service>实时跟踪输出 -
docker compose ps查看当前状态和退出码(Exit Code 列) - 退出码为非 0(如 137 表示 OOM Kill,139 表示 Segmentation Fault)能快速定位问题类型
- 结合
docker inspect <container>查看State.FinishedAt和State.ExitCode
避免掩盖问题的配置陷阱
盲目使用 restart: always 可能让故障“静默持续”:
- 应用反复崩溃又重启,日志被轮转覆盖,难以追溯首次异常
- 资源类问题(如内存溢出)可能引发雪崩,重启反而加剧压力
- 建议搭配资源限制(
deploy.resources.limits)和监控告警,而非仅依赖自动重启