Nginx proxy_pass 域名默认静态解析,需用变量+resolver实现动态DNS更新:proxy_pass http://$backend; 配合 location 内 resolver 8.8.8.8 valid=30s;,避免直接写死域名。

当 Nginx 的 proxy_pass 指向一个域名(如 proxy_pass http://api.example.com;)时,Nginx 默认在启动或重载配置时只做一次 DNS 解析,并将结果缓存为 IP 地址。若后端服务的 IP 发生变化(例如云服务弹性伸缩、DNS 轮询、故障转移),Nginx 不会自动更新,导致请求失败或转发到已下线节点。
启用动态 DNS 解析(resolver + resolve)
Nginx 官方不支持对 proxy_pass 域名做运行时自动重解析,但可通过 resolver 指令配合变量间接实现动态解析:
- 必须使用变量形式定义上游地址,例如
proxy_pass http://$backend; - 在
location或server块中配置resolver,指定 DNS 服务器(如resolver 8.8.8.8 valid=30s;) -
valid参数控制 DNS 缓存时间,建议设为 10–60 秒,避免过长导致失效,也不宜过短增加 DNS 查询压力 - 注意:
resolver不能写在http块顶层(旧版本不支持),推荐放在location内;Nginx 1.19.10+ 支持全局resolver
使用 upstream 配合 keepalive 和健康检查(推荐生产环境)
更稳定的做法是放弃直接域名代理,改用显式 upstream 块管理后端节点:
- 通过外部工具(如 Consul、Nacos、kube-proxy)或脚本定期更新
upstream配置并触发nginx -s reload - 启用
keepalive和health_check(需 stream 模块或商业版),提升连接复用与故障感知能力 - 若后端基于 Kubernetes,可直接使用 Service 名称 + CoreDNS,配合
resolver kube-dns.kube-system.svc.cluster.local valid=5s;
避免常见配置错误
以下写法无法触发动态解析,需特别注意:
-
proxy_pass http://api.example.com;—— 字面量域名,无变量,始终静态解析 -
resolver缺失或未在同级作用域生效(比如写在http块却在location中用变量) - 变量未正确赋值,例如
set $backend "api.example.com";后仍写proxy_pass http://api.example.com;(未使用变量) - DNS 服务器不可达或防火墙拦截 UDP 53 端口,导致解析超时后 fallback 到旧缓存或报错
验证是否生效
可通过以下方式确认动态解析已起作用:
- 查看 Nginx error 日志,搜索
resolving或could not be resolved相关记录 - 修改本地 hosts 或 DNS 返回不同 IP,观察 Nginx 是否在
valid时间后发出新请求并命中新地址 - 用
strace -p $(pgrep nginx) -e trace=connect抓取 worker 进程的连接目标 IP 变化










