关键不是查DNS,而是确认Nginx是否每次请求重复解析:upstream中用域名(如server api.example.com;)默认不缓存,需配合resolver+resolve(≥1.19.0)或改用IP;proxy_pass路径写法、keepalive复用及tcpdump抓包须同步验证。

排查 proxy_pass 结合 upstream 负载均衡时的解析延迟,关键不是查 DNS,而是确认 Nginx 是否在每次请求时重复做域名解析,以及 upstream 中的 server 地址是否用了未缓存的域名。
检查 upstream 中的 server 是否使用了动态域名
如果 upstream 里写的是类似 server api.example.com:8080; 这样的域名,Nginx 默认不会缓存 DNS 解析结果(除非显式配置)。每次建连都可能触发 DNS 查询,尤其在高并发或 DNS 服务不稳定时,会表现为“解析慢”或连接卡顿。
- 改用 IP 地址最直接:如
server 10.0.1.22:8080;,彻底绕过解析开销 - 若必须用域名,需启用 DNS 缓存:在 http 块中加
resolver 8.8.8.8 valid=30s;,并在 server 行后加resolve;(注意:仅 Nginx Plus 或 1.19.0+ 开源版支持) - 验证方式:临时把域名改成错误值(如
server fake-api.example.com:8080;),reload 后看 error log 是否报host not found in upstream—— 若报错,说明解析发生在 reload 阶段(静态解析);若不报错但请求失败,说明是运行时动态解析
确认 proxy_pass 是否携带 URI 导致重写干扰
proxy_pass 后跟的路径会影响 Nginx 对 upstream 的地址拼接逻辑,错误的写法可能触发隐式重定向或内部重试,间接拉长处理链路。
- 错误写法:
location /api/ { proxy_pass http://backend; }→ 实际转发为http://backend/api/,但 backend 中 server 若没配 host 头或路径处理不当,可能返回 301 或反复重试 - 正确写法:
location /api/ { proxy_pass http://backend/; }(末尾带斜杠),确保路径被截断重写 - 验证方法:开启
error_log /var/log/nginx/error.log debug;,观察日志中是否有rewrite or internal redirection cycle或多次upstream尝试记录
抓包确认底层连接建立是否卡在 DNS 或 TCP 握手
用 tcpdump 或 ss + curl 组合定位真实瓶颈环节,区分是“解析慢”还是“建连慢”。
- 在 Nginx 机器上执行:
tcpdump -i any port 53 -w dns.pcap,同时发起测试请求,查看是否真有大量 DNS 查询 - 用
curl -v http://your-nginx-host/api/test观察时间分布:关注* Trying xxx.xxx.xxx.xxx:80...和* Connected to...之间的时间差 - 若
Trying后长时间无响应,且 tcpdump 显示 DNS 请求超时或无应答,就是 DNS 层问题;若直接连到 IP 但Connected很慢,则是网络或后端 TCP 队列问题
检查 upstream keepalive 与连接复用是否失效
即使 DNS 解析正常,如果每次请求都新建 TCP 连接,也会带来额外开销。解析延迟感有时其实是连接建立延迟的误判。
- 确认 upstream 块启用了 keepalive:
upstream backend { server 10.0.1.22:8080; keepalive 32; } - 对应 proxy_pass 必须配合:
proxy_http_version 1.1;和proxy_set_header Connection ""; - 验证方式:用
ss -tnp | grep :8080查看 ESTABLISHED 连接数是否稳定复用;若连接数随 QPS 线性增长,说明 keepalive 未生效











