直接看$status字段是最高效的方式:4xx表示客户端错误,5xx表示服务端错误,均为明确异常信号;可用grep或awk快速筛选,再结合upstream_status和error.log定位真实根因。

直接看 $status 字段是最高效的方式。4xx 表示客户端请求有问题,5xx 表示服务端处理失败,两者都是明确的异常信号,无需猜测,日志里一查就定位到具体失败请求。
快速提取 4xx 和 5xx 请求
用 grep 或 awk 一行命令就能筛出全部异常:
- 查所有 4xx:grep ' 4[0-9][0-9] ' /var/log/nginx/access.log
- 查所有 5xx:grep ' 5[0-9][0-9] ' /var/log/nginx/access.log
- 合并查:grep ' [45][0-9][0-9] ' /var/log/nginx/access.log
- 统计分布:awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | grep -E '^( *[1-9]|[1-9][0-9]) [45][0-9]{2}$'
结合 upstream_status 判断真实失败环节
单看 $status 是表层结果,比如 502/504 实际是上游出问题。日志中若记录了 $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
识别高频异常背后的模式
不是单条 404 就算问题,要看是否成规律:
- 大量不同路径的 404(尤其含 /wp-admin、/.git/config、/phpmyadmin):大概率是扫描或爆破
- 同一 IP 短时间密集发 400/403:可能是恶意构造请求或爬虫绕过检测
- 502/503 集中出现在某几分钟:检查后端服务是否刚好重启、OOM kill 或负载突增
- 5xx 伴随高 $request_time(如 >5s):说明后端处理慢或阻塞,不一定是崩溃











