nginx中需通过resolver+proxy_pass或第三方模块实现动态dns解析,避免upstream静态解析导致的高可用风险;推荐内网dns、合理设置ttl与超时,并配置错误重试机制保障健壮性。

直接在 Nginx 中控制 DNS 解析频率,核心是避免静态解析“固化”、防止缓存过期后阻塞请求,同时兼顾性能与实时性。Nginx 默认对 upstream 块中的域名只做一次解析(启动时),后续永不更新——这正是高可用场景下最常被忽略的风险点。
用 resolver + proxy_pass 实现运行时动态解析
当不需要 upstream 复杂调度,仅需代理到单个可变域名(如 SaaS 接口、云服务网关)时,这是最轻量、最可控的方式:
- 在
server或location块中声明resolver,指定可信 DNS 服务器(如8.8.8.8或内网 DNS)并设valid=30s控制 TTL 缓存时长 - 用
set定义变量承载目标域名(不能直接写死proxy_pass http://example.com) -
proxy_pass引用该变量,Nginx 就会在每次新连接建立时按需解析
示例配置:
server {
listen 80;
resolver 114.114.114.114 valid=30s timeout=3s;
set $backend "api.example.com";
location / {
proxy_pass http://$backend;
proxy_set_header Host $backend;
}
}
⚠️ 注意:此方式不适用于 upstream 块,变量在 upstream 中不可用。
为 upstream 启用域名动态解析(需模块支持)
若必须使用 upstream(比如要配合 least_conn、health_check 或多节点轮询),原生 Nginx 不支持其内部域名刷新,需引入第三方模块:
-
推荐模块:
nginx-upstream-dynamic-servers(GitHub 开源,兼容主流版本) - 启用后,在
upstream的server行加resolve标志,Nginx 会按 DNS 记录的 TTL 自动重解析 - 务必在
http块顶层配置resolver,否则模块无法工作
配置片段:
http {
resolver 8.8.8.8 valid=60s;
upstream api_cluster {
server api-v1.example.com resolve;
server api-v2.example.com resolve;
least_conn;
}
server {
location /api/ {
proxy_pass http://api_cluster;
}
}
}
? 提示:DNS 提供方的 TTL 建议设为 60–180 秒,太短增加 DNS 查询压力,太长导致故障切换延迟。
规避 DNS 解析瓶颈的实用技巧
即使启用了动态解析,仍可能因超时或失败拖慢请求。以下配置能显著提升健壮性:
- 始终配
resolver_timeout 3s,防止 DNS 查询卡住整个 worker 进程 - 在
proxy_pass所在 location 中加proxy_next_upstream error timeout invalid_header http_502 http_503 http_504,让解析失败或连接异常时自动尝试下一个上游(如有 backup) - 避免在
upstream中混用 IP 和域名;混合使用会导致部分节点永远不参与动态解析逻辑 - 生产环境优先使用内网 DNS(如 CoreDNS、dnsmasq),降低外部依赖和延迟
不建议的“伪优化”做法
有些方案看似简单,实则埋下隐患:
- 定期 reload Nginx:虽能强制刷新所有 DNS,但会引起连接中断、配置校验失败风险,且无法精准控制单个域名更新节奏
- 把域名全换成 IP 写死:完全失去弹性,无法对接云服务自动扩缩、蓝绿发布或 DNS 故障转移
- 依赖客户端 DNS 缓存(如设极长 TTL):等于把负载均衡决策权交给用户本地网络,失去服务端调度能力
真正可持续的优化,是在 Nginx 层建立“按需解析 + 有限缓存 + 快速降级”的闭环机制,而非绕过 DNS 或强求绝对实时。











