你把一次查询得到的地址抄进路由规则,网站能用,一周后却不行了。规则本身没有任何改动。服务换到了另一个边缘地址,客户端解析到了别的主机名,或者会话切到了 IPv6。你面前的决定是:基于名称的规则还是显式网段才是适合这个服务的工具,而三个条件就能定下来。下面把名称与地址分开,因为两者之中只有一个稳定。

为什么一次查询不是清单

内容分发网络返回的地址,是按解析器、地区和当下时刻挑出来的。从不同网络问两次,可能得到不同的答案。只问一次就把答案当成服务的地址清单,你写下的规则就成了快照,而不是规则。把 DNS 应答当作配置的全部问题就在这里。

还有第二个缺口。一个可见的主机名很少覆盖整个应用,因为登录、媒体和 API 流量常常使用不同的名字。按地址栏主机名建立的规则可能覆盖页面却漏掉视频,这读起来像局部故障,而不是路由错误。

第三个缺口是地址族。只针对 v4 的规则,对客户端可能偏好的 AAAA 记录什么也没说。

决定域名规则还是网段的三个条件

第一,服务是否公布了你能拥有并记录在案的稳定前缀集合?如果是,显式网段既诚实又便宜。如果不是,域名规则就是唯一能跟随服务的机制。

第二,你客户端的域名机制会刷新吗?连接时只解析一次、之后再也不刷新的规则,是换了更好包装的快照。第三,该机制覆盖子域名和两个地址族,还是只覆盖你输入的名字?

回答这三个问题,选择通常就很清楚。靠猜会得到一条测试能用、上线就坏的规则。

测一个会话,而不是一个页面

先加载页面,再做真正重要的操作:登录、开始播放、上传文件。每一项都可能到达不同的主机,而失败的那一项正是规则漏掉的。

列出会话实际连接的对象,而不是页面显示的内容:

dig +short example.com A
dig +short example.com AAAA
curl -sI https://example.com | head -5

比较时让解析器保持可见,因为一条在某个解析器下能用、在另一个解析器下失败的规则,说明的是 CDN 的应答,而不是隧道。TTL 很短也意味着你记下的答案有保质期。

每种机制实际覆盖什么

两种机制在设置页上看起来可以互换,底层行为却不同。

MechanismWhat it matchesHow it fails
Domain ruleNames the client resolves, then their addressesMisses subdomains, or goes stale when refresh is off
Address routeA prefix you wrote downKeeps matching an address the service has left

内核地址路由匹配的是前缀。它根本不知道主机名是什么,所以无法跟随会换地址的服务。域名规则解析名称并路由结果;它能跟随服务,却依赖解析器、刷新行为以及客户端对子域名的处理,因此跟随名称的规则必须用客户端实际使用的解析器来测试。

两者互不为超集,所以不加说明地混用,日后必然造成混乱。

服务变化后重新核对

客户端更新或服务变更之后,把同一套会话测试再跑一遍。曾经可用的地址清单只是那段时间的证据,不是服务基础设施的永久清单。

写下哪种机制覆盖哪个主机名,以及你最后一次核对的日期。

这条记录就是能站得住脚的规则和谁都不敢碰的规则之间的差别。如果服务公布了自己的前缀清单,就用它,并注明日期。如果没有,就如实写明,并把域名规则和它的刷新行为写在旁边。

相关文章