DNS 解析失败还是 MTU 问题?请求究竟卡在哪一步
一个永远无法解析的名字会在任何连接建立之前失败;MTU 卡顿则在握手之后才开始。先确定阶段,再改动一层,然后重新测试。
两种失败给用户的却是同一句话:网站打不开。它们发生在不同层面,而这个差别决定了你要改什么。域名解析失败发生在任何连接建立之前。数据包大小问题发生在名字解析之后、握手完成之后,所以页面会先开始加载,然后卡住。先找到阶段,再去找设置。
两个不同层面的失败
解析把名字变成地址,在此之前连接中别的什么都不能开始。路径 MTU 问题出现得更晚:某个链路承受不了的包被丢弃,而发送方永远收不到通知。一个是查找失败;另一个是投递失败,只在一定大小之上才显现。
两者的症状差别可以直接观察,不需要任何工具。DNS 失败是立刻且一致的:浏览器说找不到服务器。MTU 失败是部分的:页面开始,部分资源到达,而一个大响应或一次上传卡住。
如果你的症状是部分的,就别再盯着 DNS 看。
阶段 1:名字到底能不能解析
用平台自带的查询工具,输入应用真正使用的那一个主机名。办公室里的私有名字可能需要内部解析器,而浏览器自带的加密 DNS 行为可能和操作系统的解析器不同,因此两者对同一个名字可能给出不同答案。
问一下操作系统会使用的那个解析器,然后比较:
dig +short vpn.example.com
dig +short vpn.example.com @10.0.0.53
如果解析失败,问题就在那份策略及其可达性上。不要为了拿到对比就把私有名字发给任意公共解析器,因为对比本身就会泄露你本想留在内部的名字。
阶段 2:传输停在哪里
如果名字解析成功、连接建立,就记录操作停在哪里。页面显示出来却卡在某个资源上、上传死在固定的一点、或者小请求都正常而大下载永远不结束——这些都是形状为大小的症状。完全开始不了的响应是另一种形状。
比较时把端点和应用的目标固定住,否则你同时测了两个变量。这个阶段其他原因也仍然可能:服务故障、丢包、过滤器行为以及隧道的重连,都会造成卡顿。
一次可复现的卡顿胜过十次轶事。
为什么 MTU 只在握手之后才伤人
TCP 握手用的是小包,所以它能通过一条载不动整段数据的路径。失败出现在发送方发出带禁止分片位的大包、某个链路把它丢掉、而本该报告上限的 ICMP 消息被过滤器吃掉而永远到不了的时候。接着发送方重试同样的大小,传输就卡住了。
所以症状取决于大小并且可复现,而不是随机的。这也解释了为什么 ping 主机什么都证明不了:小的 ICMP 回显能穿过一条载不动整份载荷的路径。可以的话从路径两端都测一下大小。只在一个方向出现的上限,是路由的不对称,而不是隧道的 MTU。
把大小明确测出来,而不是靠推断:
ping -M do -s 1472 203.0.113.20
tracepath 203.0.113.20
改一层,然后证明它
对名字,改掉解析器策略,再跑一次同样的查询。对大小,用 MTU 流程,记下原始取值并准备好回退,因为在不了解隧道真实 MTU 的情况下去限制 MSS,只是把一个卡顿换成另一个。
改了几项设置之后能加载一次的页面,并不能指出哪一项是修复。只改一件事,重跑同一个测试,并把结果放在你记录的第一个失败阶段旁边。
正是这份记录,才让 DNS、数据包大小和认证不至于变成一堆谁也解释不清的长期绕行。用裸 IP 去测试,是那种会改变 TLS 身份的捷径的好例子;为了对比通过而关掉证书验证,不是诊断。