<p>需启用并配置 access_log 记录 $upstream_addr、$upstream_status、$request_uri 等关键字段,通过 upstream_status 为 404/502/- 精准区分后端返回、连接失败或未触发代理,并结合 error.log 中 upstream timed out、no live upstreams 等线索交叉验证。</p>

看到 Nginx 错误日志里没报错,但反向代理就是不转发——这很常见。真正的问题往往藏在日志“没报错”的安静背后。关键不是等错误出现,而是用日志主动暴露路径、头信息和上游状态。
先确认日志是否真在记录
Nginx 默认只在出错时写 error.log,而很多代理失败(比如 404、502)其实属于“正常响应”,不会进 error.log。必须确保 access.log 在工作,并且配置了能揭示代理行为的字段:
- 检查 access_log 指令是否启用,路径是否可写(如
access_log /var/log/nginx/access.log main;) - 在 log_format 中加入关键变量:
$upstream_addr(实际连接的后端地址)、$upstream_status(后端返回状态码)、$request_uri(原始请求路径) - 示例格式:
log_format debug '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_addr $upstream_status $request_uri';
看 access.log 判定代理是否触发
如果某条请求在 access.log 中显示 upstream_addr 为空或为 -,说明根本没走到 proxy_pass 阶段——问题出在 location 匹配或静态文件拦截上:
- 检查是否有更宽泛的
location /提前截获了请求,覆盖了你的location /api/ - 临时加一句
add_header X-Location-Matched "$uri|$request_uri" always;到目标 location 块,用响应头验证是否命中 - 注意末尾斜杠:
location /api和location /api/行为不同;后者才匹配/api/v1,前者会匹配/apixxx
从 upstream_status 看清 404/502 来源
$upstream_status 是定位代理问题的核心线索:
- 值为 404 → 后端服务自己返回了 404,不是 Nginx 拦截的。立刻 curl 直连 upstream 地址(如
curl -i http://127.0.0.1:9000/api/v1/items)验证 - 值为 502 → Nginx 连不上后端:检查端口是否监听(
ss -tlnp | grep :9000)、Docker 网络是否通(容器内用host.docker.internal或服务名)、防火墙是否放行 - 值为 -(短横)→ 请求压根没发给 upstream,可能被 rewrite、return、try_files 或内部重定向终结了
配合 error.log 捕捉底层失败
虽然多数代理失败不进 error.log,但以下几类会记:
-
upstream timed out:后端响应太慢,需调大
proxy_read_timeout - no live upstreams:upstream 块中所有 server 都被标记为 down(健康检查失败或手动 down)
-
connect() failed:Nginx 根本连不上后端 IP:port,典型如 Docker 容器里写
127.0.0.1却想访问宿主机服务 - rewrite or internal redirection cycle:location 内部跳转死循环,常因 try_files 或 rewrite 配置不当引起


















