Nginx 的 resolver 指令不直接实现动态负载均衡,但为变量 proxy_pass 提供 DNS 解析能力,是动态路由和上游服务发现的前提;必须显式配置 resolver 才能支持运行时域名解析,否则会报错“no resolver defined”。

Nginx 的 resolver 指令本身不直接实现动态负载均衡,但它为基于域名的 upstream(如使用变量或 proxy_pass http://$backend)提供了 DNS 解析能力——这是动态路由和上游服务发现的关键前提。解析加速的核心在于减少 DNS 查询延迟、避免阻塞、复用缓存,并适配服务变化节奏。
resolver 必须显式配置才能支持变量 proxy_pass
默认情况下,Nginx 在启动时解析 upstream 域名并固化为 IP,不支持运行时变更。若你在 location 中写了类似 proxy_pass http://$upstream_host,Nginx 会报错 “no resolver defined to resolve …”。必须在 http 或 server 块中声明 resolver:
-
resolver 127.0.0.53 valid=30s;—— 使用本地 systemd-resolved,缓存 30 秒 -
resolver 8.8.8.8 1.1.1.1 valid=10s ipv6=off;—— 多个 DNS 服务器,禁用 IPv6 避免双栈延迟 -
resolver 10.10.1.100 timeout=2s;—— 设置单次查询超时,防卡住 worker 进程
解析加速靠缓存策略与最小化查询次数
DNS 缓存由 valid 参数控制,但实际生效还取决于 DNS 响应中的 TTL 和 Nginx 的内部行为。要真正提速:
- 将
valid设为略小于后端服务 DNS TTL(例如服务 TTL 是 60s,设valid=50s),避免缓存过期瞬间大量并发解析 - 避免在
if或频繁重写的 location 中反复拼接不同域名(如$host-$env.example.com),每次新域名都会触发首次解析 - 用
map预定义常用域名映射,减少运行时字符串计算和解析触发概率
配合变量 upstream 实现轻量级动态路由
单纯 resolver 不够,需结合变量 proxy_pass 构建动态转发逻辑:
map $arg_backend $upstream_target {
default "api-v1.example.com";
"v2" "api-v2.example.com";
"canary" "api-canary.example.com";
}
server {
location /api/ {
resolver 127.0.0.53 valid=45s;
set $backend "http://$upstream_target";
proxy_pass $backend;
proxy_set_header Host $upstream_target;
}
}
注意:proxy_pass 后必须是带协议的完整 URL(如 http://...),否则 Nginx 不会触发 DNS 解析;同时建议搭配 proxy_next_upstream error timeout invalid_header 提升容错性。
生产环境必须监控解析行为与失败降级
resolver 无内置日志开关,但可通过以下方式观测效果:
- 开启
error_log /var/log/nginx/error.log debug;(临时),搜索resolving、cached、failed关键字 - 用
nginx -t && nginx -s reload后观察 error.log 是否出现could not be resolved - 设置 fallback:当 DNS 解析失败时,用
error_page 502 503 504 /fallback.html;或返回预设静态响应,避免雪崩
不复杂但容易忽略:resolver 是全局指令,不能写在 location 内;它只影响变量型 proxy_pass 和某些第三方模块(如 lua-resty-dns),对静态 upstream 块完全无效。











