Nginx 动态解析后端域名需满足三条件:用变量触发解析、resolver 置于 location/server 块内、配置兼容版本;推荐变量+location 内 resolver 方式,加 valid=30s 控制缓存时效。

要让 Nginx 在运行时真正动态解析后端域名(比如 api.example.com),不能只加一行 resolver,关键得满足三个条件:用变量触发解析、resolver 放在正确作用域、配置与 Nginx 版本兼容。否则,哪怕 DNS 已变,Nginx 仍会一直连旧 IP,导致 502 或超时。
用变量 + location 内 resolver(最通用)
这是兼容性最好、无需升级 Nginx 的方式,适用于所有稳定版本:
- 必须把域名赋值给变量,再在
proxy_pass中引用它,例如:set $backend "api.example.com";<br>proxy_pass http://$backend:8080;
-
resolver必须写在同一个location或server块里,不能只放在http块顶层——Nginx 不会向下继承 - 加上
valid=30s控制缓存时效,避免 DNS 更新后长期不生效;太短(如 1s)会增加 DNS 查询压力,太长(如 5m)可能错过故障切换 - 确保 DNS 服务器可达(如
8.8.8.8或内网 CoreDNS),且防火墙允许 UDP 53 端口出向通信
upstream 块中启用 resolve(Nginx ≥ 1.19.0)
如果需要复用 upstream 的负载均衡、健康检查等功能,可以用这个方式:
- 全局
resolver必须已声明(推荐放在http块) - upstream 中每个
server行必须写域名(不能写 IP),并显式加resolve参数,例如:upstream backend {<br> resolve api.example.com valid=20s;<br> server api.example.com:8080;<br>} - 注意:旧版本 Nginx(resolve,仍按静态处理,不报错也不生效
常见错误写法及后果
这些配置看着合理,但实际不会触发动态解析:
-
proxy_pass http://api.example.com;—— 字面量域名,启动时只解析一次,后续永不更新 -
resolver写在http块,但location里用了变量却没重复声明resolver—— 变量解析失败,日志报could not be resolved - 写了
set $backend "api.example.com";,但proxy_pass还是写成http://api.example.com—— 完全没用上变量,白配 - DNS 返回
NXDOMAIN(域名不存在)时,Nginx 不会自动换下一个 resolver 尝试,而是直接返回 502
怎么确认真的生效了
别只靠 nginx -t 或 reload 日志判断:
- 修改 DNS 记录(比如把域名指向一个新 IP),等超过
valid设置的时间后,查看 Nginx error log,搜索resolved to,应能看到新 IP 地址 - 用
strace -p $(pgrep nginx) -e trace=connect抓 worker 进程的连接目标,观察是否随 DNS 变更而变化 - 临时把本地 hosts 指向一个假 IP,看 Nginx 是否在
valid后自动切回真实解析结果











