Nginx动态域名代理需用变量+resolver实现运行时DNS解析:set $backend "api.example.com"; proxy_pass http://$backend; 并在同location/server块配resolver 114.114.114.114 valid=30s;高稳场景推荐upstream显式定义后端。

直接在 proxy_pass 后写死域名(如 proxy_pass http://api.example.com;),Nginx 会在启动或重载时强制解析该域名。一旦 DNS 不可达、域名无效或客户环境无公网,就会报错退出,服务根本起不来。
用变量绕过启动期解析
核心思路是让 Nginx 启动时不触碰 DNS,把解析动作推迟到第一次实际请求时发生:
- 用
set指令定义变量,例如set $backend "api.example.com"; -
proxy_pass必须引用该变量,写成proxy_pass http://$backend;(不能混用字面量) - 这样启动阶段只做语法检查,不发起任何 DNS 查询
必须配 resolver,且位置要对
仅用变量还不够——Nginx 运行时需要知道找谁去查 DNS:
- 在同一个
location或server块内添加resolver指令,例如resolver 114.114.114.114 valid=30s; - 不要放在
http全局块(旧版本不支持,且作用域失效) -
valid时间建议设为 10–60 秒:太短加重 DNS 压力,太长无法及时感知后端 IP 变更 - 若客户内网有自建 DNS,优先填内网地址,避免依赖公网
生产环境更稳的替代方案
对稳定性要求高的场景,建议放弃动态域名代理,改用显式 upstream:
- 定义
upstream块,列出具体 IP 或内部 Service 名(如 Kubernetes 中用my-service.default.svc.cluster.local) - 配合
keepalive复用连接,减少握手开销 - 启用健康检查(
health_check),自动剔除不可用节点(注意:流式模块或商业版才支持 HTTP 层健康检查) - IP 变更时,只需更新 upstream 配置并执行
nginx -s reload,不中断服务
快速验证是否生效
别等出问题才排查,上线前就确认动态解析已就位:
- 修改本地 DNS 返回一个新 IP,观察 Nginx error 日志中是否出现
resolving或could not be resolved相关记录 - 等
valid时间过后,用strace -p $(pgrep nginx) -e trace=connect抓 worker 进程的连接目标,看是否切换到了新 IP - 临时把
resolver指向一个不可达地址,应看到超时日志,证明解析逻辑确实在运行时触发











