nginx反向代理动态dns解析需四件套:显式resolver(http/server块中,禁ipv6)、valid控制缓存时效、resolver_timeout设为2–5s防卡死、proxy_pass必须用变量触发运行时解析,缺一不可。

要让 Nginx 在反向代理外部域名时不再因 DNS 解析卡住而返回 502,核心不是“等得更久”,而是让解析更快失败、更快重试、更快切换——resolver 动态 DNS 解析是起点,但必须配齐四件套:显式 resolver + 合理 valid + 严格 resolver_timeout + 变量驱动 proxy_pass。
必须显式配置 resolver,且位置正确
Nginx 不读 /etc/resolv.conf,也不继承系统 DNS。漏配或错配就等于没开动态解析:
- 写在
http或server块顶层最稳妥,例如:resolver 223.5.5.5 114.114.114.114 valid=30s ipv6=off; - 避免只写一个 DNS 地址,防止单点失效
- 内网环境优先用本地 DNS(如 CoreDNS 或阿里云内网 DNS
100.100.2.136),延迟更低、更可控 - 加
ipv6=off可跳过 AAAA 查询,避免 IPv6 不通拖慢整体解析
proxy_pass 必须用变量,否则 resolver 形同虚设
直接写 proxy_pass http://api.example.com; 是启动时静态解析,改了 IP 也无感知。真正触发运行时 DNS 查询,必须走变量路径:
- 正确示例:
location / {<br> set $upstream "http://api.example.com";<br> proxy_pass $upstream;<br>} - upstream 块里的域名默认仍是静态解析(开源 Nginx),除非你用 Tengine 或 Nginx Plus 的 dynamic_resolve 模块
- HTTPS 场景下额外加两行,否则 SNI 错配会直接 502:
proxy_ssl_server_name on;<br>proxy_ssl_name "api.example.com";
resolver_timeout 要设得“快而不莽”
它不控制缓存时间,只管单次 DNS 查询最多等多久。设太短误判,设太长卡死 worker:
- 公网调用(如第三方 API):设
resolver_timeout 5s;,覆盖 P95 延迟,又不放大抖动 - 内网 DNS(如 CoreDNS):可缩到
2s,响应通常 - 严禁设 10s+ —— 一个卡住的 DNS 查询会让整个 worker 连接挂起,高并发下迅速雪崩
- 验证是否生效:开
error_log ... debug;,搜日志里是否有resolving timeout或cached字样
叠加基础容错,DNS 失败不等于服务不可用
即使 DNS 刷新及时,网络丢包、上游瞬断仍会发生。单靠 resolver 无法兜底:
- 启用自动重试:
proxy_next_upstream error timeout http_502 http_504;<br>proxy_next_upstream_tries 3;
- 每个 upstream server 加健康探测(哪怕只做连接层):
server api.example.com resolve max_fails=2 fail_timeout=15s; - 限制并发压力防连锁阻塞:
worker_connections 1024;<br>keepalive_timeout 15s;
- 若域名极少变更(如 CDN 回源地址),可考虑预解析 + /etc/hosts 绑定,彻底绕过运行时解析











