如何查看Nginx代理服务器中API请求的解析目标地址?
核心错误原因
错误日志里的no resolver defined to resolve some_ip是关键——当你用变量(比如这里的$api)指定proxy_pass目标时,Nginx不会在启动阶段解析目标地址,而是在收到请求时才去解析,这时候必须配置resolver指令告诉Nginx用哪个DNS服务器来完成解析。
查看实际请求解析地址的方法
你之前尝试用$upstream_addr报错,是因为这个变量只有在请求成功转发到上游服务器后才会生成,而你的请求因为解析失败根本没到这一步,所以变量无效。可以用以下两种方式查看解析情况:
1. 利用已开启的debug日志
你的配置里已经设置了error_log /var/log/nginx/error.log debug;,debug日志会详细记录DNS解析的全过程,包括:
- Nginx尝试使用的resolver地址
- 解析成功后得到的IP
- 解析失败的具体原因
直接过滤查看相关日志:
tail -f /var/log/nginx/error.log | grep -E "resolver|some_ip"
2. 添加自定义日志字段记录解析结果
先在server块中配置resolver,然后在API代理的location里添加自定义日志字段,记录解析后的上游地址:
server { # 保留原有所有配置... resolver 8.8.8.8 valid=300s; # 指定DNS服务器,缓存解析结果300秒 resolver_timeout 5s; # 设置解析超时时间 location ~ ^/api(/.*)$ { # 保留原有所有配置... proxy_pass $api$request_uri; # 添加自定义日志,记录解析后的上游地址 access_log /var/log/nginx/api_access.log main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' 'resolved_upstream: $upstream_resolved'; } }
这里的$upstream_resolved变量会直接记录Nginx解析得到的上游服务器地址,只要resolver配置正确且解析成功,就能在api_access.log里看到实际解析的地址。
修复502错误的方法
既然明确是缺少resolver导致的解析失败,直接在server块中添加resolver配置即可,比如:
resolver 8.8.8.8 1.1.1.1 valid=300s; # 可添加多个备用DNS服务器 resolver_timeout 5s;
添加后重启Nginx,请求即可正常转发。
另外补充:你的rewrite ^/api(/.*)?$ $1 break;和proxy_pass $api$request_uri;存在逻辑重复,因为rewrite已经移除了/api前缀,$request_uri就是处理后的路径,可简化为proxy_pass $api;,功能完全一致。
内容的提问来源于stack exchange,提问作者wittn

