隧道建立几秒后打开页面,并不能证明 DNS 现在可用,尽管工单通常这么说。那次观察中没有任何环节要求发起查询:域名可能在变更前就已解析,并从隧道从未接触过的缓存中复用。两种不同的测试会得到同一个画面。

在把功劳归于这次变更之前,先比较每个测试实际检验了什么。

页面加载不是查询

应用与解析器之间的每一层都可以在其生命周期内记住答案。操作系统保存一份,浏览器保存自己的,而长连接应用在整个会话中可能再也不解析任何东西。因此,隧道切换后的成功加载可能只是记忆的展示,而不是路由的证明。没有失败并不等于发生了查询。

这一区别会改变你接下来该测试什么。如果目标是证明新解析器能够应答,你需要一次无法由尚未清理的缓存来满足的查询。

把缓存中的成功当作此前无法访问的服务器已经恢复的证据,是这类错误中最昂贵的版本,因为它以错误的前提关闭了事件。

下结论前先数清缓存

有四个值得点名:应用自身的解析、操作系统的客户端缓存、浏览器的内部状态,以及查询最终到达的任意递归解析器。每一个都有独立的生命周期和独立的清理方式。清理一个却测试另一个,正是人们得出“清理没有起作用”这一结论的方式。一条清理命令永远无法解决问题。

否定答案也会被缓存。被报告为不存在的域名,在网络修好之后仍可能保持不存在;这会被读成隧道故障,实际上却是尚未过期的 TTL。DNS 规范描述了这些数据应当如何保存和复用。

记录事件,而不是印象

写下三者中究竟哪一项变了:记录、通往解析器的路径,或客户端设置。记录编辑按自己的时间表传播,路由变更在重新连接时生效,浏览器设置只对该浏览器有效。把它们压成单一的前后对比,会得到一条无人能够审计的时间线。

记下时间、使用的解析器和收到的答案,包括答案为否定的情况。这是别人可以核查的事实。

用同样的方式做两次比较

清理你打算测试的缓存,保留最初的观察,然后以尽可能绕过记忆的方式发起查询。明确指名解析器只能告诉你该解析器知道什么;它不会告诉你应用本来会选择哪个解析器。

resolvectl flush-caches
ipconfig /flushdns
dig +noall +answer internal.example @10.44.0.53
dig +short internal.example

在 Windows 上,客户端缓存刷新只清理 DNS 客户端缓存,别的什么也不做。它不描述浏览器的私有状态,也不刷新上游服务器,因此基于它的测试只能作狭窄解读。每次报告结果时,都要说明你清理了哪个缓存。

然后用全新请求、并在预期解析器策略生效的情况下重新测试实际应用。在不同策略下产生的结果不能直接搬用。

相关文章