bigywater.tech
Flask · 179

健康检查接口

健康检查接口看起来最简单,却有几个常见的坑:存活和就绪该分开,检查依赖要设超时,探针和业务请求共用 worker,探针的访问日志会把日志淹没。这篇用真实的 gunicorn 一项项量出来(数据库连接的健康检查见第 188 篇,容器信号见第 189 篇)。

503
依赖不可用时 /readyz 的状态码(此时 /healthz 仍是 200)
2615 ms
1 个 sync worker 被慢请求占着时,/healthz 的耗时
22 → 2
22 次请求(其中 20 次探针)的访问日志行数:默认 vs 自定义 logger_class

存活与就绪

实测 · 本机执行输出
  依赖正常       /healthz → 200 ok (43 ms)   /readyz → 200 {"checks":{"dep":"ok"},"status":"ready"} (1 ms)
  依赖被杀掉      /healthz → 200 ok (1 ms)   /readyz → 503 {"checks":{"dep":"ConnectionRefusedError"},"status":"not ready"} (1 ms)
  依赖重新起来     /healthz → 200 ok (5 ms)   /readyz → 200 {"checks":{"dep":"ok"},"status":"ready"} (6 ms)
  依赖被杀掉时,进程本身没问题(不该被重启),只是暂时不该接流量
  HEAD /healthz → 200,正文 0 字节,Content-Length 2

上一篇:Docker 部署 Flask;下一篇:优雅关闭。

依赖是一个自己起的 TCP 小服务(PING/PONG),不是真实数据库。

探针与 worker

实测 · 本机执行输出
  sync ×1                /slow 处理中时 /healthz → 200,耗时 2615 ms
  sync ×2                /slow 处理中时 /healthz → 200,耗时 9 ms
  gthread 1 进程 ×4 线程     /slow 处理中时 /healthz → 200,耗时 6 ms

依赖超时

实测 · 本机执行输出
  依赖调用不设超时             → 探针客户端 8 秒后放弃:TimeoutError
  (同时)/healthz → 200 (8 ms)
  依赖调用超时 0.5 秒         → 503 {"checks":{"dep":"TimeoutError"},"status":"not ready"} (532 ms)

探针日志

实测 · 本机执行输出
  默认 accesslog                     访问日志共 22 行,其中探针 20 行
  logger-class qlog.QuietHealth    访问日志共 2 行,其中探针 0 行

分步演示

健康检查接口
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动。gunicorn(sync、gthread 两种 worker),依赖是自己写的 TCP 服务
    • 没有验证:Kubernetes 的 liveness/readiness/startupProbe 的实际行为(本篇没有运行 K8s)、负载均衡器的健康检查参数、检查真实数据库或 Redis、就绪接口的缓存、探针的鉴权
    京ICP备2026067502号-1京公网安备11010502063487号