一次诡异的 DNS 解析问题排查
上周遇到一个挺典型的问题:同一批机器,访问某个域名时,一部分正常、一部分超时。折腾了一下午,把过程记下来。
现象
服务 A 调用 api.example.com,从机器甲发起正常,从机器乙发起就卡在连接阶段,十几秒后超时。两台机器配置一模一样,同一个镜像。
先排除网络:curl -v 显示 TCP 根本没建起来,卡在 Trying x.x.x.x...。也就是说,它连的地址不对。
第一步:看解析结果
dig +short api.example.com @114.114.114.114
dig +short api.example.com @223.5.5.5
dig +short api.example.com @8.8.8.8
结果三个解析器给出了两个不同的 IP。其中一个 IP 在我这边完全不可达。
第二步:问权威服务器
dig NS example.com +short # 拿到权威 NS
dig +short api.example.com @<权威NS>
权威服务器返回的是正确的那个。说明问题出在递归解析器的缓存上,不是域名配置错了。
为什么会这样
两种可能:
- 解析器缓存的记录过期时间很长,而域名刚刚改过 IP,缓存还没失效
- 解析器在查询过程中拿到了被污染/错误的应答,并缓存了下来
这次是第一种:域名换 IP 时 TTL 设得太长(1 小时),改完之后各处缓存陆续过期,就出现「有的机器对、有的机器错」的窗口期。
几个结论
- 排查 DNS 一定要横向对比多个解析器,只看一个往往会得出错误结论
- 能不查缓存就不查:
dig +trace或者直接问权威 NS,最快定位 - 换 IP 之前先把 TTL 调小(比如 60 秒),等旧 TTL 过期再切,能大幅缩短不一致窗口
- DoH/DoT 只保护「客户端 ↔ 解析器」这一段,解析器自己的缓存问题照样会传给你
最后是临时在 hosts 里写死了正确 IP 顶过去的。长期方案是让服务端支持配置解析器、或者干脆走内网域名。