在VPS上部署服务时,最让人不安的情况往往不是完全解析失败,而是同一域名一会儿返回A记录,下一次却得到另一条地址:应用连接漂移、证书校验偶尔异常,监控又显示主机网络仍然正常。此时应把“DNS解析漂移”当作一条需要逐层验证的链路,而不是先重启应用或盲目更换DNS。核心要分清解析器、搜索域、缓存和上游故障,否则很容易把局部现象误判成服务商故障。
如果你正在选机器,或者想先把线路和配置跑通再谈长期方案,可以先看看这几家的线路说明和技术参数:bestproxy(海外服务器),先看清带宽线路、流量策略和退款条款,再决定要不要迁。
一次完整的查询通常从系统调用入口开始。程序把域名交给VPS上的解析器,解析器再根据resolv.conf决定使用哪些DNS服务器、搜索域以及查询选项。若名称没有以点结尾,且包含的点数少于ndots阈值,解析器可能先拼接search domain逐个尝试。这个行为会让“同一条域名”在不同配置下访问到不同主机,也会使短名称被错误补全。
随后要区分两类缓存。系统或运行库可能缓存最近结果,递归DNS服务器也会按照记录的TTL保存答案。CoreDNS启用cache插件后,同样会按实例保存响应;上游返回的旧TTL、轮询记录或不同递归节点,都可能造成结果在地址之间切换。反过来,如果直接使用权威DNS查询,答案稳定但递归链路仍可能失败,这说明问题未必出在权威配置。
上游故障通常表现为超时、SERVFAIL、丢包或返回SERVFAIL前的重试,而不是稳定返回一条新的A记录。因而“结果变了”和“结果解析失败”应分别取证,不能归为同一种漂移。

第一步固定比较条件。先用dig查询完整域名,并记录返回状态、答案、TTL和服务器地址;同时读取resolv.conf中的nameserver、search、options ndots、timeout和attempts。测试短名称时,分别比较原名、拼接后的搜索域名以及带结尾点的绝对名称。带点名称若稳定,而原名漂移,优先检查搜索域和ndots,而不是立即改动上游。
第二步绕过本地路径。对比本机默认解析器与指定公共递归DNS的输出,再用dig +trace观察从根、顶级域到权威服务器的链路。如果指定递归DNS稳定、默认解析器异常,检查本机缓存、网络策略和resolv.conf;如果两者都在权威环节得到不同答案,再核对权威记录及TTL。查询时不要只看最终IP,还要看CNAME链和返回时间。
第三步检查CoreDNS。查看Corefile中forward、cache、loadbalance等插件的顺序,确认日志记录了上游响应、缓存命中和查询耗时。缓存中的旧答案与实时上游答案不一致时,先确认TTL和缓存键,再决定是否清理对应缓存;没有证据时重启CoreDNS只会让缓存暂时消失,不能证明根因。上游频繁超时或SERVFAIL,则应检查VPS到递归DNS的链路、端口和返回码。
修复决策可以归纳为:配置错误就修正resolv.conf,搜索域造成的误判就改用绝对域名或调整ndots,缓存确有陈旧数据才清理缓存,上游链路异常则处理网络或更换递归入口。借助ServLlama等工具留存多时间点的查询结果,也有助于把偶发漂移还原成可比较的证据。

确认漂移位置后,要继续看名称解析链。ndots 决定 resolver 是否先把域名视为相对名并套用 search 域。例如 ndots 为 5,a.b.c.d.e 可能触发多个候选域查询;点数达标时又会先按绝对名查询。因此一次失败可能被放大成多次请求。排查时应记录原始域名、search 域、尝试顺序和返回码,不能只看最后一个 NXDOMAIN。
进入 CoreDNS 后,要区分本机缓存与上游缓存。启用 cache 插件时,它会按 TTL 保存正向和负向结果;不同副本的缓存年龄、预加载状态及上游选择不同,可能返回不同地址。递归服务商的任一地址、GeoDNS 和 ECS 也会造成区域性差异,这通常属于有意调度。判断漂移时,应固定递归出口、来源网段和查询类型,再比较 TTL、CNAME 链与权威答案。

最容易踩的坑,是把“能解析”等同于“路径正确”。systemd-resolved 可能让 127.0.0.53 接管请求,NetworkManager、Docker 或面板脚本也可能覆盖 /etc/resolv.conf;只改文件而不重载对应服务不会生效。/etc/hosts、Java DNS 缓存、IPv6 结果及应用硬编码地址也可能绕开系统链路。测试时混用本地 stub、公网 DNS、DoH,会抹平故障边界;临时端口耗尽或丢包也常被误记为漂移。
检查可按五步执行:一是用 systemctl status systemd-resolved 确认实际解析服务,并用 readlink -f /etc/resolv.conf 核对文件来源与更新时间;二是用 resolvectl status、getent ahosts example.com 查看搜索域和最终地址;三是用 dig +trace example.com 对照权威链;四是读取 CoreDNS 的 /metrics 和 cache 日志,比较命中、过期及上游错误;五是在相同出口连续查询,记录 qname、qtype、rcode、TTL、返回 IP 和时间戳。
收口时,固定入口与出口,从应用、系统解析器、CoreDNS、递归上游到权威 DNS 逐层二分,每层只改变一个变量并保存带时间戳的响应。若权威答案一致而递归结果不同,优先检查缓存与任一调度;若系统结果正确而应用结果错误,则检查应用缓存和连接复用。这样才能把真正的DNS缓存漂移与地域分流、配置覆盖、网络抖动区分开。