nginx 中 resolver 必须显式声明在 http/server/location 块内,推荐置于 http 块顶层;需指定至少两个 dns 地址、valid= 时间控制缓存、resolver_timeout 防阻塞,且必须配合变量 proxy_pass 或 upstream resolve 才能实现动态解析。

在 Nginx 基础配置中,resolver 必须显式声明,不能依赖系统默认 DNS(如 /etc/resolv.conf)。它只在 http、server 或 location 块中生效,最稳妥的做法是写在 http 块顶层,确保全局继承。
指定 DNS 服务器的基本语法
格式为:
resolver address1 [address2 ...] [valid=time] [ipv6=on|off] [timeout=time];
常见写法示例:
-
resolver 114.114.114.114 8.8.8.8 valid=30s;—— 指定两个公网 DNS,缓存 30 秒 -
resolver 10.1.2.100 valid=15s ipv6=off;—— 指向内网可信 DNS,禁用 IPv6 防卡顿 -
resolver 127.0.0.1:5353 valid=5s timeout=3s;—— 使用本地 dnsmasq,自定义端口和超时
必须配合的参数才能真正起作用
仅写 resolver 8.8.8.8; 不够。要让 DNS 解析动态、可控,还需:
-
加
valid=时间:控制缓存有效期,不设则永不刷新,等同于静态解析 -
加
resolver_timeout:建议设为3s,避免单次 DNS 查询阻塞整个请求 - 多个地址空格分隔:主 DNS 故障时自动切到备用,提升可用性
不能放在哪些地方
以下位置写 resolver 是无效的:
-
events块 —— 语法错误,Nginx 启动失败 -
stream块 —— TCP/UDP 代理不支持该指令(需用其他模块) - 未声明作用域的裸配置 —— 指令必须嵌套在合法块内
常见误区提醒
很多人以为配了 resolver 就能自动刷新所有域名,其实不是:
- 直接写
proxy_pass http://api.example.com;—— 仍只启动时解析一次,resolver完全不生效 - 在
location中用了变量但没在同级或上级写resolver—— 会退回到不可控的系统 resolver - 只写一个 DNS 地址且未设
timeout—— 查询失败可能卡满默认 30 秒











