线上故障里,有一类很折磨人:业务间歇性连不上某域名,过几分钟又好了,curl 本机正常、部分机房失败,或容器里失败宿主机正常。最后往往查到 DNS,而不是业务代码。本帖整理排查顺序和常见坑,具体行为以各解析器实现为准。

一、先确认是不是 DNS
1. 对比:用 IP 直连(改 hosts 或 URL 写 IP)是否稳定。直连稳定而域名不稳定,优先怀疑解析。
2. 在故障瞬间抓证据:dig +trace 示例.com、dig @8.8.8.8、dig @公司内网 DNS,记录返回的 A/AAAA、SOA、Authority、应答耗时和 status(NOERROR/SERVFAIL/NXDOMAIN)。
3. 同时看客户端缓存:systemd-resolved(resolvectl query)、Docker 内置 DNS、语言运行时(JVM/Go)是否自带缓存。不同层 TTL 处理不一致时,会出现「有的进程好、有的进程坏」。

二、TTL 与缓存分层
1. 权威记录 TTL 过短(如 30s)会放大解析器压力,过长则切换 IP/摘流变慢。变更前评估:发布切换需要多快,再决定是否临时降 TTL。
2. 递归解析器、操作系统、容器、应用可能各自缓存。故障「自愈」有时只是某一层缓存过期后重新拉到正确记录。
3. 负缓存(NXDOMAIN/SERVFAIL 的缓存)容易被忽略:短时配置错误被缓存后,修对了权威区仍要等负缓存过期。

三、常见根因
1. 双栈:AAAA 存在但 IPv6 路径不通,部分客户端先试 AAAA 再回退 A,表现为偶发超时。可临时验证:curl -4 / curl -6,或检查是否应对外提供 AAAA。
2. 分线路/GeoDNS:不同出口递归到不同答案,监控探针与真实用户不在同一视角。
3. 权威或递归限流、UDP 截断转 TCP 失败、防火墙拦 53/tcp。
4. search domain / ndots 导致短域名被拼成内部名再去公网解析,多一次失败路径。
5. 服务发现混用:K8s CoreDNS、云厂商 Private Zone 与公网同名冲突。

四、排查顺序(建议)
1. 故障机上:getent hosts、dig、resolvectl status(若适用),确认「谁在答」。
2. 指定公共 DNS 与内网 DNS 对比;必要时 dig +tcp。
3. 查权威:SOA 序列是否已更新、多 NS 答案是否一致(多 NS 不一致会造成「看运气」)。
4. 应用侧:是否缓存了旧 IP;连接池是否把解析结果缓存到进程生命周期结束。
5. 变更窗口:是否刚做了 DNS 切换、证书域名变更、CDN CNAME 调整。

五、工程建议
1. 关键切流提前降低 TTL,切完再调回;保留回滚记录。
2. 监控不仅探 HTTP,也对关键域名做解析成功率与解析时延监控(分地域、分 DNS 服务器)。
3. 容器与虚拟机明确 DNS 策略,避免每人 /etc/resolv.conf 不一致。
4. 双栈环境单独验证 IPv6,或在确认通路前谨慎发 AAAA。

欢迎分享你们处理过的「假偶发」DNS 事故和监控做法。