Nginx upstream域名动态解析需三要素:resolver置于http块顶层并配valid=时间、upstream中server行写域名+resolve参数(≥1.19.9)、配合proxy_next_upstream等容错机制,缺一不可。

要让 Upstream 中的域名真正响应后端集群 IP 变更,不能只靠写个 resolver 就完事——关键在于打破“启动解析一次、后续永远缓存”的死锁。Nginx 默认对 upstream 域名做静态解析,哪怕配置了 resolver,只要没触发运行时查询机制,IP 变了照样打到旧地址,引发持续 502、超时或部分请求失败。
必须把 resolver 放在 http 块顶层并带 valid 参数
resolver 指令不继承、不自动读取系统 DNS,必须显式声明,且 valid= 是打破死锁的核心:
- 正确写法:
resolver 114.114.114.114 8.8.8.8 valid=30s;(放在http { }内) - 不加
valid=,DNS 缓存永不刷新,等于没配;设太长(如 300s),IP 变更后流量卡在旧节点上长达 5 分钟 - 避免单 DNS:至少配两个,防止单点不可用导致整个 upstream 解析失败
- 可加
resolver_timeout 5s;防止 DNS 查询阻塞请求
Upstream 必须用 resolve + 域名,且 Nginx ≥ 1.19.9
旧版 Nginx 的 upstream 域名始终静态固化,只有 1.19.9+ 才原生支持运行时动态解析:
- upstream 块中每个
server行必须写域名,末尾紧跟resolve,不能换行、不能有空格:server api.example.com:8080 resolve; - 支持单独设 TTL:
server api.example.com:8080 resolve valid=20s;,比全局valid=更灵活 - 若混用 IP 和域名(如
server 10.1.2.10:8080;),该行不参与动态解析,也不受 resolve 影响
搭配容错机制,避免 DNS 刷新窗口期出问题
DNS 查询本身可能失败、延迟或返回空结果,仅靠 resolve 不足以保障可用性:
- 每行 server 加健康检查:
server api.example.com:8080 resolve max_fails=2 fail_timeout=15s; - 启用失败重试:
proxy_next_upstream error timeout http_502 http_504;,让请求自动切到其他节点 - 设置重试次数上限:
proxy_next_upstream_tries 3;,防止无限循环 - backup 节点也要带
resolve,否则它可能长期指向过期 IP,失去兜底意义
验证是否真正在动,别信配置文件
nginx -t 只校验语法,真实效果得看运行时日志和行为:
- 修改 DNS 记录(如把
api.example.com指向新 IP),等超过valid=时间(如 30 秒) - 查
error.log:出现resolving "api.example.com"或resolved ... to 10.20.30.40才算生效 - 若频繁报
resolver not found或getaddrinfo() failed,先确认 DNS 地址能否ping、UDP 53 端口是否被拦截 - DNS 全挂时,Nginx 会继续用缓存 IP 响应,这是设计容错,不是故障











