要看Nginx把请求分到了哪台服务器,最直接的方法是查看后端响应头中的UPSTREAM_ADDR变量,或者直接查Nginx的access.log日志文件,这两处会明确记录每笔请求对应的上游服务器IP地址和端口。
为什么你需要知道请求分给了哪台服务器
大多数团队在Nginx后面挂了不止一台应用服务器,用户访问一个页面,Nginx按照负载均衡策略把请求分发到后端节点,如果某台节点出问题、接口报错、响应变慢,你必须快速确认请求到底落在了哪台机器上,才能精准排查。
只知道“Nginx把请求转发给了上游”,却不知道具体是哪一台,排查问题就得一台一台登录看日志,浪费时间,掌握了查看请求分发目标的方法,问题定位效率直接翻倍。
通过access.log查看upstream_addr
默认日志是否包含上游地址
Nginx默认的access.log格式长这样:
0.0.1 - - [21/Feb/2026:10:30:15 +0800] "GET /api/user HTTP/1.1" 200 1024 "-" "Mozilla/5.0"
这条日志只记录了客户端IP、请求时间、请求行、状态码、响应大小和UA。默认格式并不包含上游服务器地址,这是很多运维刚上手时容易踩的坑。
改造log_format记录上游IP
要看到Nginx把请求分给了谁,需要自定义日志格式,在nginx.conf的http块中加上:
log_format upstream_info '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'upstream_addr=$upstream_addr';
然后在server块或location块中调用:
access_log /var/log/nginx/access.log upstream_info;
保存后执行nginx -t检查配置语法,再nginx -s reload平滑重载,配置生效后,新产生的请求日志末尾会出现类似upstream_addr=192.168.1.15:8080的记录,这就明确告诉了你该请求被分配到了哪台后端服务器。
查看日志的操作路径
线上查看日志不一定要登录服务器,但如果只能命令行操作,常用组合是:
tail -f /var/log/nginx/access.log | grep upstream_addr
筛选特定时间段的请求:
grep "21/Feb/2026:10:30" /var/log/nginx/access.log | grep upstream_addr
按后端节点分组统计请求分布:
awk '{for(i=1;i<=NF;i++) if($i ~ /^upstream_addr=/) print $i}' /var/log/nginx/access.log | sort | uniq -c
这样能大体看出Nginx是否把请求均匀分到了各台服务器上,如果某台节点长期没有流量,说明负载均衡配置可能有问题,或者该节点已从upstream中移除。
实时查看请求分配到哪个服务器的Nginx访问日志方法
不重载配置直接查看
nginx access log查看upstream_addr这个操作,有人在生产环境不敢动配置,担心日志格式变化影响采集系统,可以先确认旧日志被备份,再调整格式,采集系统如果只解析固定字段,可以在现有格式末尾追加upstream_addr=$upstream_addr字段,不影响旧字段的解析,据Nginx官方文档说明,$upstream_addr变量的值是完整的IP:PORT格式,如果请求失败在多个上游节点间重试,该变量记录所有尝试过的地址,用逗号分隔。
排查请求被转发到多个节点的情况
请求重试会造一条日志里有多个upstream_addr值,
upstream_addr=192.168.1.15:8080, 192.168.1.16:8080
这种情况说明第一台节点未能正常完成请求,Nginx自动把请求转发给了第二台,看到这样的日志,优先检查第一台服务器的健康状况。
在Shiro配置中快速定位后端节点
Shiro作为常用的Java安全框架,通常部署在Nginx后端,当Nginx配置了多台Shiro服务节点时,可以采用以下方式确认当前请求由哪个节点处理:
添加响应头方式
在Nginx的location块添加:
add_header X-Upstream $upstream_addr;
前端开发者打开浏览器开发者工具,查看网络请求的响应头,直接看到X-Upstream字段值,即后端实际处理请求的服务器IP和端口。
在Shiro业务代码中输出机器标识
在Shiro的登录接口或认证逻辑中,把本机IP写入响应体的自定义字段中,配合Nginx的$upstream_addr双重验证,实际排查时,用这个方式定位最准确,因为能看到业务层面的节点标识和网络层的转发地址一致。
运维场景中如何快速判断
假设某天用户反馈登录接口偶发报错,你登录Nginx服务器,执行:
tail -100 /var/log/nginx/access.log | grep -E "upstream_addr=.,"
如果发现有逗号分隔的地址,直接确认是某台后端节点超时或拒绝连接导致的请求重试,接着登录该节点检查服务状态,问题定位完成。
不带日志的情况下怎么判断
借助tcpdump抓包分析
如果生产环境的Nginx日志没有开启upstream_addr,临时又不想改配置,可以用tcpdump直接在Nginx服务器上抓包:
tcpdump -i eth0 port 8080 -nn -c 100
这样能看到Nginx向后端8080端口发起连接的目标IP,但抓包查看的弊端是看不到请求对应的URL,如果Nginx代理了多个域名,需要通过端口区分。
通过后端服务器的连接状态反推
在后端服务器上执行:
netstat -an | grep :8080 | grep ESTABLISHED
看到来自Nginx服务器IP的ESTABLISHED连接,说明该服务器正在处理来自Nginx转发的请求,这个方式适合后端节点数不多、快速确认是否有流量到达的场景。
通过upstream_addr为空判断异常
日志里出现upstream_addr=(空值)的情况,通常意味着Nginx在做请求转发前就返回了响应,最常见的原因是配置了proxy_pass但后端未开始处理,或Nginx内部错误直接返回了502/504,遇到这种情况,需要检查Nginx和后端节点间的网络连通性,以及后端服务的监听状态。
配置维护中的注意事项
管理多节点Nginx集群,日志格式统一才能快速对比排查,行业通行的最佳实践是:
- 所有Nginx节点的log_format必须完全一致,否则对比日志时字段错位会误导排查
- access_log按天切割,避免单文件过大导致检索缓慢
- 日志中记录的
upstream_addr对应的是监听端口,不是健康检查端口,确认防火墙规则放行实际业务端口 - 当后端返回
5xx错误时,日志中记录的upstream_addr仍然是实际处理请求的节点地址,这点对故障定位尤其重要 - 后端节点上线或下线后,旧连接可能残留5-10秒,日志中看到的节点地址可能已经不在当前upstream列表里,等待1-2个请求周期再判断
业内专家指出,配置了upstream_addr的Nginx日志是排查分布式系统问题的第一手材料,其价值不亚于应用自身的业务日志,多数长时间跑着Nginx的团队,都会默认开启该字段,省去了临时加字段、重载配置的流程。
实际操作中的高频问题
查看Nginx配置后如何让修改生效
修改nginx.conf或conf.d下的子配置文件后,先执行nginx -t验证配置语法,输出syntax is ok才能执行nginx -s reload,这一步最多花费1分钟,但能避免语法错误导致Nginx服务中断。
为什么访问日志中没有upstream_addr
开启upstream_addr字段后,新产生的请求会记录该字段,历史日志不会补写,确认是否生效,可以实时请求一次接口,再tail -1查看最新一条日志是否包含upstream_addr=xxx。
如何确认所有请求都被记录
如果Nginx配置了自定义日志格式,但access_log指令没有和log_format关联,日志仍然用默认格式输出,检查方法是在nginx -T输出中搜索access_log,确认对应server块的access_log参数指向了正确的log_format名称。
最终结论:查Nginx请求分配到哪台服务器,核心就是让$upstream_addr变量出现在日志或响应头中,把这一条配置加入你的Nginx模板,故障排查时能少走一大段弯路。
Q&A:Nginx分配到哪个服务器的常见疑问
修改log_format后旧日志文件还能用吗
旧日志文件不会被重写或删除,只是新写入的日志行会按新格式记录,原有日志的字段没有任何变化,采集系统依然能解析历史数据,建议在修改配置前cp一份旧日志备份,防止重载配置的瞬间有异常。
nginx负载均衡查看后端服务器地址有没有不用改配置的办法
有临时方案:用ngx_http_stub_status_module模块的/nginx_status页面能看到当前活跃连接数,但无法看到具体后端地址,更直接的办法是在后端服务器上执行netstat -an | grep 8080 | grep ESTABLISHED查看来自Nginx的连接,但这个方式看到的只是连接,不能对应到具体请求,生产环境推荐的做法还是开启upstream_addr日志记录,它是最完整、最可追溯的方案,故障复盘时日志就是证据。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/791686.html


