/health接口必须纯内存计算且无io,严格控制在1秒内返回200;禁用requests查db/redis,改用psycopg2.connect(timeout=2)、redis_client.ping()和httpx.get(timeout=1.0);healthcheck需匹配应用端口并设--start-period=5s。

Flask/FastAPI里怎么写/health接口不踩Docker liveness probe超时的坑
健康检查接口不是返回200就行,Docker的livenessProbe默认只给1秒响应时间,超时直接重启容器。很多Python服务用time.sleep(0.5)模拟DB检测,一上生产就反复重启。
- 必须把所有外部依赖(DB、Redis、HTTP下游)设超时,且总耗时严格控制在
initialDelaySeconds和timeoutSeconds之下(K8s默认timeoutSeconds: 1) - 不要在
/health里查真实业务表——用SELECT 1或连接池ping()代替 - FastAPI建议用
BackgroundTasks跑轻量探测,主请求只返回缓存结果;Flask可配@cache.memoize(30)(需Flask-Caching) - 示例(FastAPI):
@app.get("/health")<br>def health_check():<br> return {"status": "ok", "timestamp": time.time()}——纯内存计算,无IO
为什么requests.get("http://db:5432")会卡死,该用什么替代
用requests连数据库端口是典型错误:它走HTTP协议,而PostgreSQL监听的是TCP流,根本不会返回HTTP响应,导致socket一直阻塞,直到Docker探针超时杀掉进程。
- 检查PostgreSQL用
psycopg2.connect(host="db", port=5432, timeout=2),捕获OperationalError - 检查Redis用
redis_client.ping(),别用requests.get("redis://...") - 检查HTTP服务用
httpx.get(url, timeout=1.0)(比requests更易控超时),禁用重定向:follow_redirects=False - 所有网络调用必须显式设
timeout,Python默认是无限等待
uvicorn启动时加--health-check-path参数有用吗
没用。uvicorn本身不提供内置健康检查路由,--health-check-path是假参数——这是很多人被文档误导的点。Uvicorn 0.29+确实加了该flag,但它只用于内部信号转发,**不会自动注册/health路由**,也不影响Docker探针行为。
- 真正生效的只有你代码里写的
@app.get("/health")(FastAPI)或@app.route("/health")(Flask) - 如果用Gunicorn + Uvicorn worker,健康检查逻辑得写在应用层,不能依赖WSGI/ASGI服务器
- 验证方式:
curl -v http://localhost:8000/health,看是否真返回200+JSON,而不是靠ps aux | grep uvicorn判断进程活着
Dockerfile里HEALTHCHECK指令和应用内/health谁优先
两者不冲突,但作用不同:HEALTHCHECK是容器层探测,/health是应用层逻辑。Docker只会执行你写的CMD命令(如curl -f http://localhost:8000/health || exit 1),它成功与否完全取决于你的/health接口是否及时返回2xx。
- 别在
HEALTHCHECK里用nc -z db 5432——这只能说明端口通,不代表DB能执行SQL - 推荐写法:
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \<br> CMD curl -f http://localhost:8000/health || exit 1
-
--start-period=5s很关键:容器刚启时DB可能还没ready,硬刚会误判失败 - 如果应用用非8000端口,
HEALTHCHECK里的localhost:xxx必须和EXPOSE及应用实际监听端口一致
最常被忽略的是时间精度:K8s的periodSeconds和Docker的--interval看着是秒级,但底层用的是纳秒计时器,微小偏差就会让探针在临界点失败。与其调参数,不如把/health做成纯内存计算——毕竟健康检查不是性能压测。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











