必须显式配置resolver,nginx不读/etc/resolv.conf;推荐http块设resolver 223.5.5.5 114.114.114.114 valid=30s ipv6=off,并配resolver_timeout 5s;proxy_pass需用变量或upstream resolve触发运行时解析。

优化 DNS 解析缓存是 Nginx 性能调优中常被忽视、却影响深远的一环。它不直接提升 CPU 或带宽,但能显著降低请求首字节时间(TTFB),尤其在代理外部服务、多可用区调度或上游 IP 频繁变更的场景下——DNS 卡顿会直接拖垮整个 worker 进程,引发 502、连接堆积甚至雪崩。
必须显式配置 resolver,Nginx 不读系统 DNS
Nginx 默认不使用 /etc/resolv.conf,也不继承宿主机或容器的 DNS 设置。若未显式声明 resolver,所有域名在启动或 reload 时仅解析一次,结果永久缓存,后续 IP 变更完全无感知。
- 推荐写在 http 块顶层,确保全局生效: resolver 223.5.5.5 114.114.114.114 valid=30s ipv6=off;
- 至少配两个 DNS 地址,避免单点失效;内网环境优先用本地 CoreDNS 或 dnsmasq(如 10.0.1.10)
- valid=30s 是关键:它让 DNS 结果最多缓存 30 秒,过期后才触发新查询,实现“动态更新”基础
- 加 ipv6=off 可跳过 AAAA 查询,防止 IPv6 不通导致整体解析延迟升高
resolver_timeout 要设得快而不莽
这个值不是“等多久”,而是“最多忍几秒”。它的作用是让卡住的 DNS 查询快速失败,释放 worker 连接,避免一个慢查询拖垮整条流水线。
- 公网调用(如第三方 API):设为 resolver_timeout 5s;,覆盖 95% 的主流 DNS(8.8.8.8 / 114.114.114.114)响应,又不因偶发抖动误判
- 内网自建 DNS(如 CoreDNS 延迟稳定在 50ms 内):可缩至 2s
- 严禁设为 1s 或更低:UDP 重传、ECS 查询、跨洲际路由都可能超 1s,反而大量触发 502
- 严禁设为 10s+:高并发下,一个卡死的 DNS 查询会让 worker 连接挂起,迅速耗尽 worker_connections
proxy_pass 必须用变量或 upstream resolve 触发运行时解析
直接写 proxy_pass http://api.example.com; 是静态解析,resolver 和 timeout 全部无效。
- 变量方式(兼容所有 Nginx 版本):
set $backend "api.example.com:8000";
proxy_pass http://$backend; 注意补 proxy_set_header Host api.example.com;,否则部分后端无法正确路由 - upstream + resolve(Nginx ≥ 1.19.0): upstream backend { server api.example.com:8080 resolve valid=20s; } 更适合负载均衡场景,自动支持多 IP 轮询与健康探测
配合基础容错机制才能真正稳住延迟
DNS 缓存只是第一步。真实网络中还有丢包、瞬断、上游切换等问题,需叠加防御:
- 启用 upstream keepalive:复用已解析 IP 的 TCP 连接,避免每次回源都握手+slow-start
- 配置 proxy_next_upstream error timeout http_502;:DNS 解析失败返回 502 时,自动切到备用 upstream 或返回兜底响应
- 限制并发压力:worker_connections 2048; 与 keepalive_timeout 15s; 防止 DNS 卡顿引发连接堆积
- 验证是否生效:开 error_log /var/log/nginx/error.log debug;,搜索日志中是否有 resolving "api.example.com" 或 cached 字样











