先查 /var/log/nginx/error.log 中 resolver timeout 等关键词,再验证 resolver 配置位置与作用域、域名实测解析结果、系统环境(如 k8s search 域、alpine musl 兼容性),即可精准定位 dns 解析异常根源。

直接看 /var/log/nginx/error.log 中是否反复出现与 DNS 解析超时强相关的错误线索,再结合 resolver 配置、域名解析实测和系统环境交叉验证,就能快速定位问题根源。
重点搜索 error.log 中的 DNS 超时关键词
打开错误日志,用以下命令快速筛选关键信息:
- resolver timeout:明确表示 Nginx 使用的 resolver 服务器无响应或响应过慢
- could not be resolved 或 no resolver defined:说明 proxy_pass 域名未被成功解析,且未配置有效 resolver
-
getaddrinfo() failed:底层调用失败,常见于空变量、拼写错误、短域名缺 search 域(如 K8s 中用
redis而非redis.default.svc.cluster.local) - host not found in upstream:配置加载期就失败,说明启动或 reload 时 DNS 不通,不是运行时问题
- no peer_addr:不是 DNS 错误本身,而是 DNS 没返回 IP 导致连接无目标地址,需回溯确认是否真没解析出 A 记录
验证 resolver 配置是否真正生效
Nginx 不默认使用系统 DNS,必须显式配置 resolver 才能支持运行时解析。常见失效原因包括:
- 只在
http块写了resolver,但在stream模块代理 TCP 流量时没单独配置——stream必须独立配 resolver -
proxy_pass写成变量形式(如set $upstream "api.example.com"; proxy_pass http://$upstream;),这会强制每次请求都走 resolver,无法缓存结果,极易触发超时 -
resolver指令位置错误,比如写在了不覆盖 proxy_pass 的 location 外层,导致作用域失效 - 未设置
valid=time(如resolver 10.48.189.10 valid=60s;),导致解析结果永久缓存,无法应对后端 IP 变更
在 Nginx 环境中实测 DNS 解析行为
别只信 nslookup,要模拟 Nginx 实际调用方式:
- 在 Nginx 所在机器执行:
dig your-upstream-domain @10.48.189.10 +short(替换为你配置的 resolver 地址),对比响应时间与 TTL - 若用容器或 K8s,进 Pod 执行:
cat /etc/resolv.conf,确认 nameserver 是否指向 coredns,search 域是否完整(如缺default.svc.cluster.local会导致短域名解析失败) - Alpine 镜像(musl libc)用户注意:musl 默认禁用 EDNS0,某些内网 DNS 会拒绝响应;可临时换 Ubuntu 镜像或加
--dns=8.8.8.8启动验证 - 检查 IPv6 干扰:若上游只监听 IPv4,但系统优先查 AAAA 记录且超时,可能跳过 A 查询;可临时禁用 IPv6:
sysctl -w net.ipv6.conf.all.disable_ipv6=1
关联访问日志判断影响程度
启用自定义日志格式,暴露 DNS 解析耗时线索:
- 添加
$upstream_connect_time字段:它包含 DNS 解析 + TCP 握手时间。若该值持续 >100ms,且占$request_time比例超过 20%,DNS 是主要瓶颈 - 对比
$upstream_header_time和$upstream_response_time:若两者同步升高、差值小,说明卡点在连接建立阶段,而非后端处理 - 观察连接来源 IP 分布:若大量新建连接来自不同源 IP(而非复用少数连接),说明 keepalive 未生效,根源往往是 DNS 未缓存,导致 upstream 名称无法命中已有连接池











