容器里加上健康检查:从“进程在跑”到“服务可用”
容器里加上健康检查:从“进程在跑”到“服务可用”
把应用放进容器后,看到容器状态是“运行中”,并不代表用户已经能正常访问。进程可能刚启动,配置还没加载完;也可能应用接口已经返回,但数据库连接池仍不可用。部署平台如果只看进程是否存在,就可能把尚未准备好的实例接入流量。
健康检查的作用,是用一个轻量、可重复的探测,把“进程活着”和“服务能够工作”区分开。下面用 FastAPI 和 Docker Compose 说明一个最小实现。
先提供一个轻量的探测接口
from fastapi import FastAPI
app = FastAPI()
@app.get('/healthz')
def healthz():
return {'status': 'ok'}
这个接口只检查 Web 服务本身能否响应,适合作为存活检查。实际项目还可以增加 /readyz,检查服务是否完成初始化,以及必须的依赖是否可用。依赖检查应设置短超时,失败时只返回状态,不要把数据库地址、异常堆栈或凭据写进响应。
在 Compose 中配置探测
如果镜像里包含 Python,可以用标准库访问接口,避免为了健康检查额外安装 curl:
services:
api:
build: .
ports:
- '8000:8000'
healthcheck:
test: ['CMD', 'python', '-c', 'import urllib.request; urllib.request.urlopen("http://127.0.0.1:8000/healthz", timeout=2)']
interval: 30s
timeout: 3s
start_period: 20s
retries: 3
interval 控制探测间隔,timeout 限制单次等待时间,retries 决定连续失败几次后标记为不健康。start_period 给应用启动和初始化留出宽限期,避免冷启动期间被过早判定失败。具体数值应根据服务实际启动时间调整。
存活和就绪检查不要混为一谈
存活检查回答“进程是否卡死,需要重启”;就绪检查回答“现在是否适合接收请求”。例如,应用进程仍在运行,但数据库正在故障切换时,它可能仍然存活,却暂时不具备处理业务请求的条件。支持探针配置的编排平台可以分别使用这两种信号;只有一个 Docker 健康状态时,也应先明确该检查是服务存活还是业务就绪,避免把短暂的依赖故障直接变成反复重启。
几个容易忽略的细节
第一,检查地址要从容器内部访问。127.0.0.1 指向容器自身,适合探测同一容器里的 API;宿主机端口映射主要给容器外的客户端使用。第二,应用服务通常需要监听 0.0.0.0 才能接受容器网络流量。第三,探测应当快速、幂等,不要每隔几十秒就写数据库、创建云资源或调用昂贵的外部接口。第四,依赖超时和网络波动要有清楚的判定策略,否则探测本身可能制造额外负载。
启动后可以用 docker compose ps 查看健康状态,用 docker compose logs api 对照启动日志。若一直显示 starting 或变成 unhealthy,先在容器内手动访问探测接口,再检查端口、启动时间和超时设置。健康检查提供的是运行状态信号,不能替代日志、监控和真实请求验证。
为服务补上合理的健康检查,能让本地开发、自动化部署和故障排查共享同一套“何时算准备好”的判断。把检查做得轻、准、可解释,比单纯追求更频繁的探测更有帮助。
- 点赞
- 收藏
- 关注作者
评论(0)