$upstream_addr用于记录Nginx负载均衡实际转发的后端地址,需Nginx 1.7.5+、正确配置upstream和proxy_pass,在log_format中添加该变量即可在日志中查看IP:PORT及重试路径。

在 Nginx 日志中记录 $upstream_addr,是观察负载均衡请求实际转发到哪个后端节点的最直接方式,能帮你快速识别流量倾斜、个别节点异常或 upstream 配置问题。
确认 Nginx 版本与 upstream 配置有效
$upstream_addr 是 Nginx 内置变量,但仅在请求真正经过 proxy_pass(或 fastcgi_pass 等)且成功选中后端时才有值。如果请求被缓存命中、返回 503、或未进入 upstream 流程(如被 rewrite 拦截),该变量为空或显示 “-”。
- 确保你使用的是 Nginx 1.7.5+(推荐 1.16+),旧版本可能不支持完整地址信息(如端口、重试地址)
- 检查
upstream块已正确定义,且proxy_pass指向该 upstream 名称(而非直连 IP),否则$upstream_addr不会生效 - 若启用
proxy_next_upstream,一次请求可能触发多次转发,$upstream_addr默认只记录**最终成功响应的后端地址**;如需记录所有尝试,需配合$upstream_addr的历史变量(见下文)
在 log_format 中添加 $upstream_addr
编辑 Nginx 配置(通常在 http 块),定义包含该变量的日志格式:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'"$upstream_addr" $upstream_response_time $request_time';
然后在 server 或 location 中引用:
access_log /var/log/nginx/access.log main;
重启或重载 Nginx 后,日志行末尾会出现类似 10.0.1.10:8000, 10.0.1.11:8000(表示重试过)或 10.0.1.12:8000(单次成功)的内容。
区分主备、多级 upstream 或重试行为
$upstream_addr 在发生重试或使用 backup 服务器时,会以逗号分隔列出所有参与过的地址(按执行顺序)。例如:
-
10.0.1.5:8080, 10.0.1.6:8080:第一次发给 5 超时/失败,第二次成功发给 6 -
10.0.1.7:8080, 10.0.1.8:8080, 10.0.1.9:8080:连续两次失败,第三次才成功(假设配置了max_fails=2) -
10.0.1.10:8080:无重试,直达主节点 -
-:未进入 upstream(如静态文件命中、4xx 错误、rewrite 跳转)
注意:$upstream_addr 不包含协议或域名,只输出 IP:PORT(或 unix:/path,如果用 socket)。若需更精细追踪(如区分集群区域),建议结合 $upstream_http_x_backend_id 等自定义响应头,由后端主动返回标识。
配合其他变量做有效分析
单看 $upstream_addr 只知“去了哪”,还需关联响应时间与状态码才能判断是否健康:
-
$upstream_response_time:对应每个$upstream_addr中的地址(逗号分隔,顺序一致),如"10.0.1.5:8080, 10.0.1.6:8080"对应"0.001, 0.023" -
$upstream_status:同理,记录每次尝试的状态码(如"502, 200") -
$upstream_http_*:可提取后端返回的特定 header,比如$upstream_http_x_app_version,辅助定位版本灰度问题
日志采集后,可用 awk、Logstash 或 Grafana Loki 快速统计各地址请求数、平均延时、错误率,生成后端健康看板。











