健康检查看起来是最简单的接口,在 Django 里却会踩到前面几篇讲过的坑:ALLOWED_HOSTS、SSL 重定向、会话中间件。这篇用探针的真实视角请求一遍,再把存活与就绪分开,看数据库挂了会怎样。
Host: 10.0.0.5(Pod IP),http → 400 Host: example.com,http → 301 https://example.com/healthz/ Host: example.com,https → 200
探针从集群内部访问,Host 通常是 Pod IP,协议是 http。前者违反 ALLOWED_HOSTS(第 122 篇),后者触发 SSL 重定向(第 121 篇)。也可以用 SECURE_REDIRECT_EXEMPT 豁免路径、把 Pod IP 加进 ALLOWED_HOSTS,这两种做法本文没有测。
Host: 10.0.0.5,http → 200 响应 b'ok' 数据库查询 0 次 Set-Cookie: False Host: example.com,http → 200 响应 b'ok' 数据库查询 0 次 Set-Cookie: False
它必须放在 MIDDLEWARE 的第一位,并且不要调用 request.get_host()。代价是它不走任何后续中间件,也就没有任何认证与日志。
[数据库运行中]
/ready/ → 200 {"ready": true} 用时 53.7 ms
/live/ → 200 ok 用时 0.1 ms
[数据库已停止(端口拒绝连接)]
/ready/ → 503 {"ready": false, "error": "OperationalError"} 用时 54.4 ms
/live/ → 200 ok 用时 0.1 ms存活探针回答「进程还活着吗」,不应当依赖数据库;就绪探针回答「能处理请求吗」,可以检查数据库。第一次请求 /ready/ 要新建数据库连接,所以耗时远高于 /live/。
/ready/ → 503 {"ready": false, "error": "OperationalError"} 用时 2053 ms给探针里的数据库连接设置 connect_timeout,让它在探针自己的超时之内失败。