直接用 $upstream_status 做健康度评分不现实,需通过日志聚合分析错误率、超时占比等指标,再分段加权映射为0–100健康度分数,并支持实时计算与告警联动。

直接用 $upstream_status 做健康度评分不现实——它只记录每次请求后 upstream 返回的 HTTP 状态码(如 200、502、504),单次值无法反映服务稳定性。真正可行的做法是:**在 Nginx 日志中记录该变量,再通过日志聚合分析,计算一段时间内的错误率、状态码分布等指标,进而映射为健康度分数**。
1. 在 access_log 中捕获 $upstream_status
确保 Nginx 配置中将 $upstream_status 写入访问日志,这是后续分析的基础:
log_format upstream_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$upstream_addr $upstream_status $upstream_response_time';注意:$upstream_status 在请求未转发到 upstream(如 499 客户端关闭、500 内部错误但未触达后端)时为“-”,需在分析阶段识别并归类。
2. 按时间窗口统计关键健康指标
从日志中提取每分钟/每 5 分钟的以下维度,作为评分输入:
- 错误率:5xx 状态码(500、502、503、504)请求数 ÷ 总请求数;
-
超时占比:状态为
504的请求占比(反映 upstream 响应超时); -
异常连接占比:状态为
502或503的请求占比(反映 upstream 不可用或拒绝); - 非 2xx/3xx 主流响应占比:排除 200、201、301、302 等常见成功/跳转码,统计其余状态出现频率(如大量 429 表示限流过严)。
3. 映射为 0–100 健康度分数
不建议线性映射。推荐分段加权打分,例如:
- 错误率 ≤ 0.5% → 基础分 90;每 +0.5% 扣 5 分(≤ 3% 时扣至 75);
- 504 占比 > 1% → 额外扣 10 分;> 5% → 额外再扣 15 分;
- 502/503 出现 ≥ 1 次 → 直接扣 20 分(表示服务中断风险);
- 若 1 分钟内无任何 upstream 记录(即全为 “-”)→ 健康度强制设为 0(Nginx 未转发请求,可能 upstream 配置失效或全部 down)。
最终得分 = max(0, min(100, 基础分 + 各项调整))。
4. 实时化与告警联动(可选进阶)
用轻量工具(如 Logstash + InfluxDB / Prometheus + nginx-lua-module)实现实时采集与计算:
- 用
nginx-lua-module在请求结束时将$upstream_status上报到本地 metrics 端点,避免日志 IO 瓶颈; - Prometheus 抓取后,用 recording rule 计算 5 分钟错误率、504 率等;
- 设置告警:健康度
这样就把原始的单次状态码,转化成了可观测、可量化、可告警的业务健康信号。


















