docker健康检查必须验证业务真实就绪状态,而非仅端口连通;需按应用冷启动耗时设--start-period(如120s),匹配响应稳定性调优--interval/--timeout,--retries设3~5,并通过dockerfile声明能力、编排层定义策略,最终联动监控与负载均衡实现闭环。
要让 docker 健康检查真正在企业环境里起作用,不能只写个 curl -f /health 就完事。核心是:检查必须反映业务真实就绪状态,参数必须匹配应用冷启动节奏,结果必须能被编排系统或运维流程有效利用。
健康检查命令必须验证业务可用性,不是端口通不通
很多团队踩坑在于用 curl -f http://localhost:80 检查 Nginx 静态页——容器进程在、端口开着,但后端数据库连不上、缓存没加载、配置没拉取,服务照样不可用。
- Spring Boot 项目应调用
/actuator/health?show-details=always,并在配置中启用management.endpoint.health.show-details=when_authorized,同时确保HealthIndicator实现了 DB、Redis、MQ 等关键依赖的探活逻辑 - Go/Python 服务建议自建
/healthz接口,内部执行连接池 ping、关键配置校验、本地缓存 warmup 标志位检查 - 避免纯 TCP 检查(如
nc -z localhost 8080),它无法区分“进程存活”和“服务就绪”
关键参数必须按应用特征调优,不能套模板
默认 30s 间隔 + 3 次失败就标 unhealthy,对 Spring Boot 或含复杂初始化逻辑的服务大概率误杀。
-
--start-period 是最常被低估的参数:设为实际冷启动耗时的 1.5 倍。例如实测应用平均启动需 72 秒,这里至少设
120s,否则前 2 分钟所有失败都计入重试,直接变 unhealthy -
--interval 和 --timeout 要匹配接口响应稳定性:若健康接口 P95 响应是 1.8s,
--timeout设 3s 合理;若偶发到 4s,就该设 6s,避免抖动触发误判 - --retries 建议设 3~5:设 1 容易因网络瞬断误判;设 10 又会导致故障发现延迟太久,影响 SLA
配置层级要分清:镜像级定义能力,服务级定义策略
HEALTHCHECK 写在 Dockerfile 里是声明“我能被怎么检查”,而 docker-compose.yml 或 Kubernetes 中的配置才是决定“这次怎么查”。两者配合才灵活。
- Dockerfile 中统一写基础指令,例如:
HEALTHCHECK --interval=30s --timeout=5s --retries=3 --start-period=120s \CMD wget --quiet --tries=1 --spider http://localhost:8080/health || exit 1 - docker-compose.yml 中按服务差异化覆盖:
MySQL 用mysqladmin ping,API 网关用curl -f http://localhost:8000/readyz,且各自设不同start_period和retries - 若基础镜像自带 HEALTHCHECK 但不适用,显式写
HEALTHCHECK NONE关闭,再在上层重新定义
状态必须可观察、可联动,否则就是摆设
健康状态只有被监控系统采集、被负载均衡器识别、被告警规则覆盖,才算真正落地。
- 用
docker inspect myapp | jq '.State.Health'查看实时状态,重点关注Status、FailingStreak和最近 5 条Log记录,这是排障第一入口 - 在 Traefik / Nginx Ingress 中开启
health-check并对接容器健康状态,自动摘除 unhealthy 实例,无需人工下线 - Prometheus 配合
cadvisor或自定义 exporter 抓取container_health_status指标,设置告警:连续 2 分钟unhealthy触发 oncall - 注意:Docker 自身不会仅因 health 变 unhealthy 就重启容器——必须配合
--restart on-failure或由 Kubernetes 的 livenessProbe 触发动作











