应以 $upstream_status 为准判断链路健康:2xx 表示后端成功但需结合响应时间,4xx 多为业务问题,5xx 表明后端故障;需按 upstream_addr + upstream_status 聚合定位异常节点,并关注重试与“假活”现象。

直接看 $upstream_status 字段,它才是后端真实返回的状态码,不是 Nginx 自身返回的 $status。链路是否健康,关键不在“有没有错”,而在于“错从哪来、谁在错、错得频不频繁”。
盯住 upstream_status 而不是 status
Nginx 日志里 $status 是它自己给客户端返回的状态(比如 502、504),属于“代理层结果”;而 $upstream_status 才是后端服务实际响应的 HTTP 状态码(如 200、500、404)。判断链路健康,必须以 $upstream_status 为准:
- 2xx 表示后端处理成功,但需结合
$upstream_response_time看是否响应过慢 - 4xx 多为业务逻辑问题(如参数错误、未授权),单个实例高频 401/403 可能是鉴权配置异常
- 5xx 是后端故障信号,特别是某台
$upstream_addr集中出现 500/503,大概率该实例已失联或崩溃
按 upstream_addr + upstream_status 聚合定位问题节点
健康分布不是统计“总错误率”,而是识别“哪个地址错得多”。用日志快速筛查:
- 查各实例的错误码分布:
awk '{print $8,$9}' /var/log/nginx/upstream.log | grep "^[45]" | sort | uniq -c | sort -nr($8=upstream_status,$9=upstream_addr) - 找最常失败的后端地址:
awk '$8 ~ /^[45]/ {print $9}' /var/log/nginx/upstream.log | sort | uniq -c | sort -nr | head -10 - 注意重试痕迹:若某行日志中
$upstream_addr是10.0.1.10:8000, 10.0.1.11:8000,说明第一次请求失败后 Nginx 自动重试了另一节点——此时两个地址都要查,不能只盯第一个
结合 response_time 判断“假活”节点
有些后端虽返回 200,但耗时远超正常水平(比如平均 200ms 的接口突然持续 3s+),属于“假健康”。在日志中提取:
- 查慢响应中的错误码:
awk '$10 > 2.0 {print $8,$9,$10}' /var/log/nginx/upstream.log | sort -k3nr | head -20($10 是$upstream_response_time,单位秒) - 对比同实例的快慢响应比例:如果某 IP 的 200 响应中,30% 超过 2s,而其他实例均
用 vts 模块实时看状态码分布
光靠日志滞后,建议启用 nginx-module-vts,访问 /status/format/json 可拿到实时指标:
-
upstreamZones下每个 upstream 的responseCodes字段,直接给出 2xx/3xx/4xx/5xx 的每秒计数 - 配合
requestCounter和inBytes,能算出错误率趋势(如 5xx 占比连续 5 分钟 >5% 就该告警) - 再通过
nginx-vts-exporter接入 Prometheus,对特定 upstream 的 5xx 率设置动态阈值告警(例如:过去 10 分钟均值 +2σ)


















