很多“网站打不开”或者“接口突然异常”的问题,根本还没走到 TCP 和 HTTP,就已经在 DNS 这一跳出了偏差。只要域名没有正确解析到目标地址,后面的连接、握手和请求就都没有意义。

DNS 排障最重要的不是记住记录类型,而是先确认:客户端到底查到了什么、从哪里查到的、这个结果和预期是否一致。

先建立一个最小排障视角

遇到域名相关问题时,第一反应不要直接说“DNS 挂了”,而是先把问题拆成三件事。

第一,域名有没有被成功解析。

第二,解析结果是不是你预期的 IP 或 CNAME。

第三,不同 DNS 服务器返回的结果是否一致。

很多时候,问题不是“解析失败”,而是“解析到了错误的地方”。这两类故障在现象上都可能表现为访问异常,但处理方式完全不同。

最常用的几个命令

先记住下面这几条就够了。

1
2
3
4
5
dig example.com
dig example.com +short
dig @8.8.8.8 example.com
dig @119.29.29.29 example.com
curl -v https://example.com

dig 用来直接看解析结果,curl -v 用来验证后续请求最终连接到了哪里。前者解决“域名查到了什么”,后者解决“请求实际走向哪里”。

如果只想快速看结果,+short 很方便;如果想看完整过程和权威信息,保留默认输出更有价值。

一次标准的排查顺序

一个比较稳的顺序是这样。

先在本机执行:

1
dig example.com

重点先看 ANSWER SECTION、TTL 和返回的记录值。如果返回了 CNAME,就继续对 CNAME 的目标域名再查一层,不要以为第一次看到名字就结束了。

接着换公共 DNS 做对比:

1
2
dig @8.8.8.8 example.com
dig @223.5.5.5 example.com

如果不同 DNS 返回结果不一致,就说明问题可能出在本地递归解析链路、运营商缓存或区域调度策略上,而不一定是权威 DNS 本身故障。

最后再用请求工具验证:

1
curl -v https://example.com

这里要关注输出里的连接目标 IP。因为你真正要确认的是,解析结果是否真的被后续请求用到了,而不是只停留在命令行输出里。

什么时候应该抓包

如果 dig 看起来正常,但应用层仍然表现异常,就可以进一步抓 DNS 包看看现场。

1
sudo tcpdump -i any port 53 -nn

抓包时重点看三件事。

第一,请求到底发给了哪个 DNS 服务器。

第二,返回包里给出的答案是什么。

第三,请求有没有重试、超时或者根本没有响应。

如果你再把抓到的结果放进 Wireshark 里,会更容易看清查询 ID、记录类型和应答时延。对刚开始练习的人来说,DNS 是非常适合入门抓包的主题,因为它短、清晰、反馈快。

常见误判

DNS 排障里最常见的误判有三个。

第一,把“域名能解析”误认为“服务一定可用”。其实 DNS 正常只代表找到了地址,不代表目标端口能连上,也不代表 HTTPS 证书正确。

第二,把“我这里正常”误认为“所有地方都正常”。DNS 天然就可能因为区域、缓存和调度策略而返回不同结果,所以排查时一定要比较多个视角。

第三,只看本地缓存结果,不看权威链路。如果你怀疑记录刚更新、TTL 未过期或者调度结果异常,必须比较不同递归 DNS 返回值,而不是只看一次本机输出。

一个值得自己做的小实验

你可以选一个自己熟悉的域名,做下面这组实验。

1
2
3
4
5
dig domain.example
dig @8.8.8.8 domain.example
dig @223.5.5.5 domain.example
curl -v https://domain.example
sudo tcpdump -i any port 53 -w dns-demo.pcap

实验时把下面几个问题写下来。

  • 本机默认 DNS 是谁。
  • 不同 DNS 返回结果是否一致。
  • TTL 分别是多少。
  • curl 最终连到了哪个 IP。
  • 抓包里 DNS 请求和响应耗时大概多少。

只要把这个实验认真做一遍,你对 DNS 的理解就会从“知道它负责域名解析”变成“知道它在现场里到底是怎么工作的”。

小结

DNS 排障真正的起点,不是背 A、AAAA、CNAME 这些名词,而是先学会确认一条请求在真正连出之前,域名到底解析成了什么。只要把这第一跳看清楚,后面的 TCP、TLS 和 HTTP 判断才会更稳。很多线上问题看起来复杂,真正拆开之后,往往就是从 DNS 这一步开始偏掉的。