Nginx 无原生“节点存活率”,但可通过 nginx_upstream_check_module 主动健康检查(如 /health 接口+http_2xx 判断)+ check_status JSON 状态页,实时获取各节点 up/down 状态;再借助 curl/jq 或 Prometheus 计算存活率。
Nginx 本身不自带“节点存活率”这个统计值,但可以通过健康检查模块 + 状态页暴露 + 简单计算,实时掌握各节点是否在线、多久没失败、当前是否被标记为 down,从而间接反映存活状态。关键不是算百分比,而是让运维一眼看清谁健康、谁异常、何时变的。
启用主动健康检查并绑定真实业务状态接口
被动靠 max_fails 触发下线太滞后,必须用主动探测。推荐使用 nginx_upstream_check_module(OpenResty 默认含,或需手动编译):
upstream 块中配置探测逻辑,例如:upstream api_backend {server 10.0.1.10:8080;server 10.0.1.11:8080;check interval=5 rise=2 fall=3 timeout=1 type=http;check_http_send "GET /health HTTP/1.1rnHost: api.example.comrnrn";check_http_expect_alive http_2xx;default_down on;}
rise=2 和 fall=3 防抖动,避免网络瞬断误判;check_http_expect_alive http_2xx 是重点:只认 2xx 为健康,拒绝把返回 {"status":"DOWN"} 或 503 Service Unavailable 的节点当活节点;default_down on 表示启动时先标记为 down,等首次探测成功再上线,避免“假启动”。配置可读的状态监控页面,直接显示每个节点实时状态
光有检查不行,得能看。用 check_status 指令暴露结构化数据:
location /status {check_status json;# 输出 JSON,含 ip、port、status、rise/fall 计数、last_check_time 等allow 10.0.1.0/24;deny all;}
访问 http://your-nginx/status 可得到类似:
{"servers": {"total": 2,"server": [{"index": 0,"upstream": "api_backend","name": "10.0.1.10:8080","status": "up","rise": 5,"fall": 0,"type": "http","port": 8080,"check_duration": 0.002,"check_status": "http_2xx"},{"index": 1,"upstream": "api_backend","name": "10.0.1.11:8080","status": "down","rise": 0,"fall": 5,"type": "http","port": 8080,"check_duration": 0.001,"check_status": "http_503"}]}}
这个输出里,status 字段就是当前存活判断结果,“up”即存活,“down”即已剔除——这就是最直接的节点存活状态。
从状态页推导“存活率”的实用方法
虽然 Nginx 不输出 存活率 = up_count / total_count × 100%,但你可以:
"status": "up",那就是 80%;curl -s http://localhost/status | jq '.servers.server[] | select(.status=="up")' | wc -l
再除以总数,就是当前存活率;
nginx-module-vts 或自定义 Lua exporter 抓取 /status,提取 upstream_down{server="10.0.1.11:8080"} 1 这类指标,再用 PromQL 计算:100 * count(upstream_down == 0) by (upstream) / count(upstream_server) by (upstream)
就是按 upstream 分组的实时存活率。
补充:让状态更可信,避开常见陷阱
/health 路径却返回 200 OK 却内容是 {"status":"DOWN"} —— 检查逻辑要进响应体,不是只看状态码;OpenResty 可用 log_by_lua_block 解析 JSON 并重设状态;/health,建议在后端加白名单,或额外配一条 type=tcp 探测兜底;interval=5 太长?可压到 2 秒,但需确保后端 /health 接口轻量、无 DB 查询,否则反成压力源;/status 不能暴露公网,务必限制 allow IP 段,避免泄露集群拓扑。不复杂但容易忽略