Docker Healthcheck实现容器级应用就绪态检测,需区分就绪态(/readyz校验DB/Redis/配置)与存活态(/health轻量探测),通过--start-period延迟检查、curl -f严格校验、503失败响应等确保真实就绪。

在Linux中用Docker Healthcheck实现容器级应用就绪态自动检测,关键不是“容器是否在运行”,而是“应用是否真正准备好处理请求”。这需要绕过进程存活的假象,直击业务逻辑层——比如API能响应、数据库连得上、缓存已预热。Docker原生的HEALTHCHECK指令就是为此设计的,它不依赖外部工具,由docker daemon原生执行,结果直接写入容器状态,可被编排系统(如Swarm、Kubernetes)或负载均衡器消费。
明确就绪态与存活态的区别
就绪态(Readiness)关注的是“能否接收流量”,而存活态(Liveness)只管“进程还在不在”。很多应用启动后要加载配置、连接DB、初始化缓存,可能耗时几十秒。若健康检查在启动瞬间就开始跑,极大概率误判为失败。所以必须区分两者:
-
就绪检查应带初始延迟:用
--start-period参数(Docker 17.05+),让容器先运行一段时间再开始第一次检查,避免抢在应用初始化完成前就失败 -
就绪检查路径需反映真实就绪条件:比如
/readyz端点内部应校验DB连接池可用、Redis ping通、必要配置项加载成功,而不仅是返回HTTP 200 - 避免和存活检查混用同一端点:/health适合做存活探测(轻量、快速),/readyz更适合就绪探测(稍重、全面)
在Dockerfile中声明就绪态健康检查
把就绪逻辑固化进镜像,保证环境一致性。以下是一个典型ASP.NET Core或Spring Boot类应用的Dockerfile片段:
# 每10秒检查一次,单次超时3秒,连续4次失败才标为unhealthy,启动后等待45秒再开始首次检查 HEALTHCHECK --interval=10s --timeout=3s --retries=4 --start-period=45s \ CMD curl -f http://localhost:8080/readyz || exit 1
注意:curl -f会严格校验HTTP状态码,非2xx/3xx即报错;|| exit 1确保失败时返回退出码1,Docker才能识别为不健康。
编写真正有意义的就绪端点
后端应用必须提供一个能体现“就绪”语义的HTTP接口。不能只是return "OK"。例如:
- 检查数据库连接是否活跃(执行
SELECT 1而非仅连通性) - 验证Redis是否可写(
SET health:check "ok" EX 10) - 确认关键配置项(如密钥、第三方API地址)已加载且格式合法
- 对有依赖的服务(如消息队列),发起一次轻量级探活调用
该端点响应应快速(建议≤1s),失败时返回503(Service Unavailable),成功返回200,并在响应体中简明说明通过了哪些子检查。
验证与调试就绪态检测效果
部署后别只看docker ps,要主动查健康状态细节:
- 运行
docker inspect --format='{{.State.Health.Status}}'查看当前状态(starting / healthy / unhealthy) - 用
docker inspect --format='{{json .State.Health.Log}}'看最近几次检查的起止时间、退出码和输出(curl的响应内容也会被记录) - 手动执行健康命令模拟:进入容器
docker exec -it,然后运行sh curl -v http://localhost:8080/readyz,确认返回符合预期
若长期卡在starting,优先检查--start-period是否设得太短,或/readyz端点本身启动慢、有阻塞。











