最高效的方式是直接分析 $status 字段,5xx 表示服务端异常,需结合结构化日志、$upstream_status 和 error.log 定位真实故障环节。

直接看 $status 字段是最高效的方式。5xx 表示服务端处理失败,是明确的异常信号,日志里一查就能定位到具体失败请求。重点不是“有没有 5xx”,而是“哪些 5xx 在什么时间、哪个接口、哪类后端上集中出现”。
用结构化日志提取稳定准确的状态码
默认 `combined` 格式中 `$status` 位置不固定,受 `$http_user_agent` 或引号干扰,`awk '{print $9}'` 容易出错。应显式前置并用强分隔符隔离: ```nginx log_format status_first '$status | $remote_addr [$time_local] "$request" $body_bytes_sent "$http_referer" "$http_user_agent" $request_time $upstream_response_time'; access_log /var/log/nginx/status.log status_first; ``` 这样 `$status` 恒为第 1 字段,`awk '{print $1}'` 即可安全提取,避免解析歧义。快速统计分布与识别突增模式
结构化后,一行命令就能产出趋势线索: - 全量统计:`awk '{c[$1]++} END {for (i in c) print i, c[i]}' /var/log/nginx/status.log | sort -n` - 聚焦 5xx 并附带路径:`awk '$1 ~ /^5[0-9]{2}$/ {print $1, $4}' /var/log/nginx/status.log | head -20` - 每小时 5xx 数量趋势:`awk '$1 ~ /^5[0-9]{2}$/ {gsub(/\[/, "", $2); print substr($2, 1, 13)}' /var/log/nginx/status.log | sort | uniq -c`关注是否成规律:
- 大量 502/504 集中出现在某几分钟 → 后端可能刚重启、OOM kill 或负载突增
- 5xx 伴随
$request_time > 5s→ 后端处理慢或阻塞,不一定是崩溃 - 同一
$upstream_addr的 5xx 率持续高于均值 3 倍 → 检查该节点超时配置与实际耗时是否匹配
结合 upstream_status 定位真实故障环节
单看 `$status` 是表层结果,必须对照 `$upstream_status`(需 log_format 包含)判断真实失败环节: - `$status=502` 且 `$upstream_status="-"`:Nginx 根本没连上后端(端口未监听、防火墙拦截) - `$status=502` 且 `$upstream_status="500"`:后端应用已响应,但返回了 500 错误 - `$status=504` 且 `$upstream_status="-"`:后端响应超时(`proxy_read_timeout` 过短或后端卡死)关联错误日志缩小根因范围
访问日志中的 `$time_local` 是本地时间,要和 `error.log` 对齐: - 从 `access.log` 提取某条 5xx 请求的时间,例如 `[07/Jun/2026:03:22:18 +0800]` - 在 `error.log` 中搜索相近时间点:`sed -n '/07\/Jun\/2026:03:22:[17-19]/p' /var/log/nginx/error.log` 重点关注提示词:`upstream timed out`、`Connection refused`、`no live upstreams`、`recv() failed`不复杂但容易忽略











