一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

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 字段决定是否重启容器:

  1. always:不管退出码是 0 还是非 0,立即重启——适合必须常驻的服务,如 Nginx、Redis
  2. unless-stopped:同 always,但若你手动执行过 docker stop,则不再自动拉起——生产环境最常用
  3. on-failure[:max]:仅当退出码非 0 时重启,可限制最多重试次数(如 on-failure:3)——避免无限崩溃重启循环
  4. no:默认行为,退出后不重启——适用于调试、一次性任务

需要配合健康检查提升判断精度

单纯靠进程退出码有局限:有些应用进程没死,但已卡死或无法响应请求(例如死锁、内存泄漏后假活)。这时单靠 restart 策略无法触发恢复。建议在 Compose 中启用 healthcheck

  1. 定义周期性探测(如 curl -f http://localhost/health || exit 1
  2. 设置超时、重试间隔和失败阈值
  3. 当健康检查连续失败达到阈值,Docker 会将容器状态标记为 unhealthy
  4. 注意:健康状态本身不会触发重启,但可配合外部工具(如 watchtower、自定义脚本)或上层编排系统(如 Swarm、K8s)做进一步动作

日志与退出码是排查关键线索

容器异常中断后,第一时间应查看日志确认根本原因:

  1. docker compose logs -f <service> 实时跟踪输出
  2. docker compose ps 查看当前状态和退出码(Exit Code 列)
  3. 退出码为非 0(如 137 表示 OOM Kill,139 表示 Segmentation Fault)能快速定位问题类型
  4. 结合 docker inspect <container> 查看 State.FinishedAtState.ExitCode

避免掩盖问题的配置陷阱

盲目使用 restart: always 可能让故障“静默持续”:

  1. 应用反复崩溃又重启,日志被轮转覆盖,难以追溯首次异常
  2. 资源类问题(如内存溢出)可能引发雪崩,重启反而加剧压力
  3. 建议搭配资源限制(deploy.resources.limits)和监控告警,而非仅依赖自动重启

热门栏目