在Nginx中为虚拟主机单独指定DNS需在server块内使用resolver指令并配合set+proxy_pass变量形式;resolver作用域敏感,server内配置优先于http级,且必须设valid参数避免永久缓存。

在 Nginx 的 server 块中为当前虚拟主机单独指定 DNS 服务器,需使用 resolver 指令,并配合变量形式的 proxy_pass 才能生效。Nginx 不允许在 upstream 块中直接使用变量域名,所以该方式仅适用于单目标代理场景(如代理到一个动态域名),不适用于多节点负载均衡。
resolver 必须写在 server 或 location 块内才能作用于当前虚拟主机
resolver 是作用域敏感指令,可放在 http、server 或 location 块中。若只希望某一个 server 使用特定 DNS(比如隔离公网与内网解析策略),应显式声明在该 server 块顶层:
server {
listen 80;
server_name api.example.com;
# 仅此 server 使用内网 DNS,不继承全局 resolver
resolver 10.1.2.100 valid=30s timeout=3s ipv6=off;
location / {
set $backend "backend.internal.svc";
proxy_pass http://$backend;
proxy_set_header Host $backend;
}
}⚠️ 注意:
-
resolver不能写在upstream、events或stream块中; - 若同时存在
http块和server块中的resolver,以最近的作用域为准(即server内的会覆盖http级配置); -
valid=30s是关键——没有valid参数,DNS 结果将永久缓存,等同于静态解析。
配合 set + proxy_pass 才真正启用运行时解析
Nginx 默认对 proxy_pass http://example.com 这类字面量域名仅启动时解析一次。要让每次新连接都按需查 DNS,必须满足两个条件:
- 使用
set定义变量承载域名(不能直接写死) -
proxy_pass引用该变量(如http://$backend)
否则即使写了 resolver,也不会触发动态查询。
多 DNS 备援与超时控制增强稳定性
为防止单点 DNS 故障或响应延迟拖慢请求,建议:
- 列出多个可信 DNS 地址,空格分隔
- 显式设置
timeout和resolver_timeout
resolver 10.1.2.100 10.1.2.101 valid=30s timeout=3s; resolver_timeout 3s;
这样当首个 DNS 无响应时,Nginx 会自动尝试下一个,且单次查询超过 3 秒即放弃,避免阻塞请求。
不推荐在 location 内重复声明 resolver
虽然语法允许,但易遗漏或错配(例如不同 location 用了不同 DNS 却未统一管理)。如非特殊需求(如灰度流量走独立 DNS),应统一放在 server 块顶部,保持清晰可维护。


















