Nginx 的 resolver 机制本质是异步非阻塞 UDP 查询,需显式配置 resolver、resolver_timeout 和 valid 参数,并配合变量式 proxy_pass 才能实现真正的非阻塞 DNS 解析。

Nginx 本身不提供“非阻塞 DNS 解析器”这一独立组件,它的 resolver 机制本质是异步、非阻塞的 UDP 查询 + 超时控制,但必须正确配置才能真正避免 worker 进程卡死、TTFB 拉高。关键不在“换解析器”,而在激活并约束 resolver 的运行时行为——让 DNS 查询快进快出,失败不拖累整体。
resolver 必须显式启用且作用域正确
Nginx 默认不查 /etc/resolv.conf,也不用系统解析器。若没配 resolver,变量式 proxy_pass 会直接报错或退化为不可靠行为。
- 写在
http { }块顶层最稳妥,例如:resolver 223.5.5.5 114.114.114.114 valid=30s ipv6=off; resolver_timeout 4s;
-
valid=30s是核心:它强制缓存最多 30 秒,到期后才触发新查询,避免每次请求都查 DNS;没有它,resolver 形同虚设。 -
ipv6=off可省去 AAAA 查询环节,尤其在纯 IPv4 环境下,能减少一次潜在延迟。
proxy_pass 必须用变量触发实时解析
静态写法 proxy_pass http://api.example.com; 在配置加载时就解析一次 IP 并固化,后续永不更新,resolver 完全不介入。
要激活非阻塞解析,必须走变量路径:
- 正确示例:
location /api/ { set $upstream "api.example.com:8000"; proxy_pass http://$upstream; proxy_set_header Host api.example.com; } - 注意:
http://协议头不能省;Host 头需手动补全,否则后端可能路由失败。
resolver_timeout 不是越小越好,而是要匹配网络现实
它不是“加速 DNS”,而是“快速放弃不可达查询”,防止一个慢查询拖垮整个 worker。
- 公网环境(调第三方 API):设为
4–5s,覆盖 95% 的 8.8.8.8 / 114.114.114.114 响应,又不致频繁误判 502。 - 内网 DNS(如 CoreDNS 或 dnsmasq):可设为
2s,因响应稳定、延迟低。 - 绝对避免
1s或30s:前者易因 UDP 重传超时引发大量无效 502;后者会让 worker 长时间挂起,放大并发毛刺。
真正降低延迟还需组合防御
resolver_timeout 单独起不了作用,必须配合其他机制形成闭环:
- 启用
proxy_next_upstream error timeout http_502;,DNS 解析失败时立即切备用 upstream 或返回兜底页。 - 使用本地缓存 DNS(如部署 dnsmasq 到 127.0.0.1:53),把 resolver 指向它,利用其重试、缓存和 TTL 感知能力,大幅压低超时概率。
- 对固定上游,优先用静态
proxy_pass http://10.20.30.40:8000;,彻底绕过运行时解析。
不复杂但容易忽略。


















