Nginx负载均衡层记录真实后端地址需在log_format中使用$upstream_addr变量,该变量仅在proxy_pass生效且完成upstream通信时返回被选中后端IP和端口,配合upstream_trace日志格式及access_log指令启用即可精准追踪请求转发目标。

要在 Nginx 负载均衡层记录真实后端地址(即请求最终转发到的 upstream server),关键是在 log_format 中正确引用 $upstream_addr 变量,并确保它在 proxy 场景下有值。
确认 $upstream_addr 在负载均衡场景下有效
$upstream_addr 是 Nginx 内置变量,仅在使用 proxy_pass、fastcgi_pass 等反向代理指令后,且请求实际完成 upstream 通信时才有值。它记录的是被选中的后端服务器地址(含 IP 和端口),若发生重试,会以逗号分隔多个地址(如 10.0.1.2:8080, 10.0.1.3:8080)。
- 确保配置中存在
proxy_pass指向一个 upstream 块或具体地址 - 避免在未触发代理的 location(如静态文件服务)中依赖该变量,此时值为空
- 若使用 keepalive 或 connection reuse,该变量仍反映本次请求实际连接的后端
定义含 $upstream_addr 的 log_format
在 http 块中自定义日志格式,推荐包含请求标识、客户端信息、上游路径等关键字段:
log_format upstream_trace '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'upstream_addr="$upstream_addr" ' 'upstream_response_time=$upstream_response_time ' 'request_id=$request_id';
-
upstream_addr="$upstream_addr"是核心,用引号包裹便于日志解析 -
$upstream_response_time建议一并记录,用于比对延迟与节点关系 -
$request_id(需配合map或random_index模块生成)可串联全链路请求
在 server 或 location 中启用该日志格式
将自定义格式应用到实际处理负载均衡的 server 块:
server {
listen 80;
server_name example.com;
<pre class="brush:php;toolbar:false;"># 生成唯一 request_id(可选但强烈推荐)
map $request_id $req_id {
"" $request_id;
default $request_id;
}
# 或使用更稳定的生成方式(如基于时间+随机数)
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 启用自定义日志
access_log /var/log/nginx/upstream.log upstream_trace;
}
}
- 日志必须写在
location或server块内,不能只在http块声明而不调用 - 确保
/var/log/nginx/目录存在且 Nginx 进程有写入权限 - 若使用 syslog 或远程日志,需额外配置
access_log syslog:...
验证与排查常见问题
部署后检查日志是否真实输出后端地址:
- 执行
curl -I http://your-lb/触发一次请求 - 查看
/var/log/nginx/upstream.log,确认upstream_addr="192.168.10.5:8080"类似内容出现 - 若始终为空:检查是否误用了
return、rewrite跳过 proxy_pass;或 upstream 块配置错误导致 fallback 到 error_page - 若出现
"-":说明该请求未进入 upstream 流程(例如匹配了其他非 proxy location)











