要实现 upstream 动态后端域名轮询,需三者协同:http 块顶层配置 resolver 及 valid 参数、upstream 中 server 域名后加 resolve、nginx ≥1.19.9;并辅以健康检查与容错机制。

要让 upstream 块真正实现动态后端域名轮询,关键不是“写对语法”,而是让 Nginx 在运行时持续感知 IP 变更,并把新地址纳入负载均衡池。静态写死域名或只配 resolver 都不行——必须三者协同:全局 resolver + valid 缓存控制 + server 行显式 resolve。
必须在 http 块顶层声明 resolver 并设 valid
resolver 不是可选项,也不能放在 upstream 或 location 里。它必须出现在 http 块最外层,且带 valid= 参数:
-
正确写法:
http { resolver 10.96.0.10 8.8.8.8 valid=30s; ... }(K8s 环境推荐 CoreDNS 地址) - valid=30s 是核心:它强制 Nginx 每 30 秒检查一次 DNS 是否更新;不加这个,就等于只在启动时查一次
- 建议配至少两个 DNS 地址,防止单点失效;可加
resolver_timeout 5s;避免查询卡住请求
upstream 中每个 server 必须用域名 + resolve
仅声明 resolver 还不够。upstream 要“活起来”,server 行必须满足两个硬条件:
- server 后写的是**域名**(如
api-svc.default.svc.cluster.local:8080),不能是 IP - 域名后紧接
resolve,中间不能换行、不能空格,例如:server api-svc:8080 resolve; - Nginx 版本需 ≥ 1.19.9(开源版已原生支持,无需第三方模块)
配合健康检查与容错才真正可靠
DNS 动态解析只是第一步。真实环境中,IP 可能刚更新但服务还没就绪,或 DNS 查询失败。需叠加基础防护:
- 每个 server 加
max_fails=2 fail_timeout=15s,快速剔除临时不可达节点 - 在 location 中配置
proxy_next_upstream error timeout http_502 http_504;,失败自动切下一节点 - 避免滥用
backup:若用了,backup 节点也得带resolve,否则它可能长期指向过期 IP
验证是否真正在轮询新地址
别只信配置文件。实际生效要看运行日志和行为:
- 修改 DNS 记录(如把域名指向新 IP),等超过 valid 时间(如 30 秒)后,查 error.log 是否出现
resolved api-svc ... to 10.244.1.5 - 用
nginx -t只校验语法,不触发解析;nginx -s reload也不刷新 DNS 缓存 - 若频繁看到
resolver not found,先确认 DNS 地址可达、UDP 53 端口未被拦截











