必须结合upstream_status、upstream_addr和时间维度分析Nginx日志,才能准确识别前端配置异常、网关瓶颈或后端故障;仅看access_log的$status会掩盖真实问题。

直接看 Nginx 的 status 状态码(即 access_log 中的 $status)只能反映网关对外返回结果,容易掩盖真实问题。真正评估网站整体运行健康度,必须结合 upstream_status(后端真实响应)、upstream_addr(具体哪台机器出问题)和时间维度,才能区分是前端配置异常、网关自身瓶颈,还是后端服务失常。
重点不是“有没有500”,而是“谁在返回500、什么时候开始变多”
只统计 access_log 里的 $status 会漏掉关键信息:
-
$status = 502/503/504是网关层报错,但无法判断是后端挂了、超时了,还是 upstream 配置根本没生效; -
$status = 200不代表业务成功——后端可能返回空内容、JSON 格式错误、或耗时长达数秒; - 大量
$status = 429可能是限流策略过严,而非服务异常;$status = 404持续上升可能指向路由配置错误或前端资源路径变更。
必须启用并解析 upstream_status 日志
默认日志不记录后端真实状态,需主动配置结构化格式:
- 在
http块中定义:
log_format upstream_full '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent $upstream_status $upstream_addr $upstream_response_time $request_time'; - 在对应
server或location中启用:
access_log /var/log/nginx/access_upstream.log upstream_full; - 注意:
$upstream_status为-表示请求压根没发出去(如 DNS 失败、upstream 名写错),这类也得计入异常总量,不能忽略。
按维度聚合分析,识别健康拐点
用日志工具或简单脚本,按分钟/5 分钟切片统计以下指标:
-
总 upstream 请求量:所有非
-的记录数; -
5xx 率:
$upstream_status为 500–599 的请求数 ÷ 总量; - 4xx 异常率:匹配 400–499 的数量 ÷ 总量(关注 429、401、403 是否突增);
-
超时占比:单独提取
$upstream_status = 504的数量 ÷ 总量; - 连接失败率:状态为 502 或 503 的数量 ÷ 总量;
-
空响应率:状态为 200 但
$body_bytes_sent < 10的占比(提示后端返回空体)。
下钻到节点级,避免“平均健康”的假象
同一时间窗口内,对每个 $upstream_addr 单独计算上述指标。例如快速查看最近一小时各节点 5xx 率:
awk -v start=$(date -d '1 hour ago' '+%d\/%b\/%Y:%H:%M') \
'$0 ~ start && $8 ~ /^5[0-9]{2}$/ {addr[$9]++; total[$9]++} \
$0 ~ start {total[$9]++} \
END {for (a in addr) printf "%s %.2f%%\n", a, addr[a]/total[a]*100}' \
/var/log/nginx/access_upstream.log | sort -k2nr
若发现某节点 504 率持续高于其他节点 3 倍以上,基本可定位为该实例网络延迟或资源瓶颈,而非全局故障。


















