去年底有位做外贸独立站的朋友找我,说站已经迁到新服务器了,DNS 控制台里的 A 记录他也亲手改成了新 IP,nginx 也确认跑在新机器上。可当天晚上客服就炸了:老客户下单后跳到空白页,新客户却完全正常。他一开始怀疑是新服务器被墙了,我让他拿自己的手机流量试了一次正常;又让他在旧服务器上看访问日志日志里居然还有零星请求,来源 IP 很杂,看着像真实用户。
问题就出在"改了记录但没给缓存留时间"这一件事上。DNS 解析从来不是"改完立刻全球生效"的按钮,它是一层层带有效期的缓存,TTL 设的是 86400(一天),那份旧答案就可能在各地递归服务器和用户本机里躺满 24 小时。真正让这次迁移多花了 6 个小时的,还有一串连锁反应:旧机器上装的监控代理还在往同一个 IM 群推数据,新旧两台服务器共用一个数据库连接串,切换当天晚上数据库连接数直接翻倍。
如果你手上有站点正准备换服务器、换 IP 或者做域名迁移,这两台可以先放进备选:狗云DOGYUN(高性价比云服务器,多机房可选)、RackNerd(全球VPS,特价常推)。机器选好了不等于切得顺,切顺的关键在解析这一层。
一、真正决定"多久生效"的不是 A 记录,是 TTL
很多人第一次碰到 DNS 解析不生效,会反复去控制台点保存、看解析记录对不对、有没有拼错 IP。这几步没错,但真正让你等上几十分钟甚至几小时的,是 TTL 这个字段。
TTL(Time To Live)说白了就是一句话:"这条解析答案,在各层缓存里最多能放多久。"权威 DNS 服务器返回给递归服务器时,会把这个数字一起带上,递归服务器就按它计时,计时到了才回头重新问一次权威服务器。所以 TTL 是 300,意味着递归服务器最多缓存 5 分钟;TTL 是 86400,那答案就能在缓存里待满一天。
你改 A 记录的那一刻,只是改掉了权威服务器上"以后要给的答案"。已经发出去的那份带旧 IP 的答案,还躺在各个地方计时。这就是所谓的"缓存未过期"。TTL 越大,切换越慢,但解析本身越稳、少查询、少负担;TTL 越小,切换快,但 DNS 查询量上去了,而且如果权威服务器偶尔抖一下,客户端就会大面积解析失败。所以业内的通行做法是:正常期用一个中等偏大的 TTL(比如 600 到 3600),确定要迁移的前一天,把 TTL 先降到 60 或 120,等旧缓存自然过期干净,再动 IP。

二、缓存一共分几层:不查清楚就没法预判"多久全网生效"
DNS 缓存不是一坨,而是分散在至少六个地方,每一层独立计时。这也是为什么"我这边已经生效了,你那边还没生效"这种对话每天都在发生。
第一层是浏览器缓存。Chrome、Edge 这类浏览器对 A 记录有自己的内存缓存,TTL 不会被无视,但用户不关页面就会一直用旧的。这层的影响范围最小,刷新一下就好。
第二层是操作系统和本地解析器缓存。Windows 上有 DNS Client 缓存,可以用 `ipconfig /flushdns` 清掉;Linux 上如果你跑着 systemd-resolved 或者本机 dnsmasq,它也会缓存。另外很多机器上装着像 NextDNS、Cloudflare 1.1.1.1 这类本地 DNS 客户端,它们自己维护缓存和规则,这一层经常被忽略。
第三层是递归 DNS 服务器缓存。这是影响面最大的一层。你在运营商的 DNS、114、公共 DNS(223.5.5.5、8.8.8.8)上查到的旧 IP,全都来自这里。每个省、每个运营商、每个公司出口的递归节点各算各的缓存时间,谁也不通知谁。
第四层是中间缓存设备。运营商的透明代理、企业出口网关、公共 WiFi 的 DNS 转发盒子,甚至一些路由器的"智能 DNS"功能,都会自己再缓存一份。
第五层是 CDN 边缘节点。如果你的域名挂在 CDN 后面,边缘节点不仅缓存 DNS 结果,还缓存 HTTP 响应。解析切过去了,边缘还在回源到旧服务器,这才是最容易漏掉的一层。
第六层是应用层自己的缓存。你的程序如果把解析结果写进了自己的内存缓存、Redis、或者配置文件里,那它跟 DNS 一点关系都没有,必须单独重启或刷新。我那次遇到的数据库连接数翻倍,本质上就是应用层还握着旧地址的连接。

三、我这次为什么多花了 6 小时:三个叠加的错误
错误一:TTL 是切前一天才降的,降完 20 分钟就改了 IP。这是最典型的一个错。降 TTL 的意义在于"给旧答案一个自然退出的窗口",你得让旧 TTL 的缓存走完,至少等一个完整周期。从改 TTL 到改 IP,中间至少隔一天,或者至少等 30 分钟以上(取决于原来的 TTL)。我们当时只隔了 20 分钟就动了 IP,结果各递归节点里至少 30% 的旧答案还活着。
错误二:只切了主域,漏了子域和 CDN 回源。那个站 www 指向 CDN,api.example.com 是直连解析,还有一个后台用的 old.example.com 直连旧服务器。前面两个切了,后台域名忘了改,结果运维同事访问后台时一直连到旧机器上,旧机器上又没有数据库数据,还以为数据库数据丢了,白慌了一场。
错误三:没有提前在旧服务器上"止血"。正确的顺序不是切完 DNS 就完事,而是先在旧服务器上挂一个 301 或者返回自定义提示的页面,同时保留旧站一段时间,这样即使有人缓存没过期,访问体验也是"跳转到新站"而不是白屏。可我们当时是直接把旧机器的 Web 服务停掉了,于是缓存没过期的那部分用户看到的就是彻底的 502。
这三件事叠在一起,切换当天晚上出现了最糟的组合:老用户报错、新用户正常、监控数据两边混着、数据库连接数翻倍、回滚又怕把新流量也搅乱。折腾到后半夜才理顺,整个过程比预期多了 6 个小时。

四、切换的正确顺序:一份能直接照着做的清单
第一步,选时间窗。避开周五下午和任何大促、投放高峰。切换窗口至少留出两倍旧 TTL 的时长,如果旧 TTL 是 86400,就意味着你要一整天的等待期。
第二步,提前一天把 TTL 降到 60。在权威 DNS 控制台把记录 TTL 改成 60,然后等。这个等待期间可以顺便确认新服务器上的站点、证书、数据库连接都是好的。
第三步,逐条核对要改的记录。别只改 www,把 A、AAAA、CNAME、泛解析、TXT 里的 SPF/MX 记录都列一张表出来。特别注意 IPv6:如果网站配了 AAAA 记录,而你的机器只有 IPv4,用户走 IPv6 访问就会失败,但大多数排查工具默认只测 IPv4,很容易漏。
第四步,改 IP。把 A 记录指到新服务器,CNAME 的指向也别忘。改完立刻用 dig 验证,指定一个公共 DNS 服务器查,避开本机缓存:
dig @223.5.5.5 example.com +noall +answer
返回的 Answer 里如果还带 TTL 数字,看看它是 60(说明这是刚查到的,缓存已刷新)还是一个很大的数(说明你查到的仍是旧缓存)。想看递归链路上的每一跳,用 dig +trace example.com,它会一路把根域、顶级域、权威服务器串给你看,某个节点返回的 TTL 很大,就是它卡住了。
第五步,旧服务器不要立刻关。在上面挂一个 301 或友好提示页,至少保留 24 到 48 小时。等确认没有旧 IP 的流量了再停服务、回收资源。
第六步,同步改应用层的配置。数据库连接串、回调地址、白名单 IP、第三方支付和监控的 webhook,这些都藏在代码和配置文件里,不会因为 DNS 变了而自动跟着变。

五、真出岔子了怎么回切
切换当天发现新服务器有问题,必须回切。回切最大的坑是:这时候新服务器已经有流量了,你把 DNS 改回去,这些正在访问新机器的用户一样会遇到问题。所以回切不是"改 A 记录"一个动作,而是三步:
先把新服务器上的问题确认清楚,是配置错了还是机器本身有问题,别在两个都不确定的状态之间来回横跳。然后在旧服务器上把服务恢复注意,如果你在旧机器上挂了 301 跳转页,得先把它改回正常服务,否则回切之后老用户会被无限重定向。接着再把 A 记录指回旧 IP,同样带着 TTL 一起改,最后用 dig 在几个不同地区的公共 DNS 上验证结果。
回切的等待时间同样取决于当前 TTL。如果你在切之前已经把 TTL 降到 60 并且过了足够久,那回切就是 60 秒级的事,最多几分钟。如果没降 TTL,回切可能又是一个小时起步。
再补一句实操建议:切换期间把老 IP、新 IP 都写进监控,让告警明确区分"打到旧机器的请求"和"打到新机器的请求"。我那晚最花时间的就是从一堆混在一起的 5xx 里分辨到底是谁在报错。

六、几个反复被问到的细节
问:解析改完,多久算"完全生效"?答:理论上最长的那条缓存过期就完事,也就是最长 TTL;实际上还要看你覆盖了多少递归节点和企业出口。建议按"最长 TTL + 30 分钟"来估算,别按自己这一台机器算。
问:能不能在解析前面挂一个自己的接口做切换?答:技术上可以,用 CNAME 指向一个自己的调度域名,由你的接口决定返回哪个 IP,这样切换是秒级的。但它多了一跳、多了一个故障点,你自己接口挂了就是全站挂了。对绝大多数站点来说,把 TTL 降好、给足等待时间,比引入一层自建调度省心得多。
问:本地缓存怎么清?答:Windows 用 `ipconfig /flushdns`,Linux 上 systemd-resolved 用 `resolvectl flush-caches`,用 dnsmasq 的可以重启服务。但要清楚,清本地缓存只解决你这一台机器,别人机器上的缓存你管不了。
问:怎么确认到底哪一层还在用旧 IP?答:分三步。先 `dig +trace` 看递归链路上的 TTL,再从不同网络环境(家里宽带、公司网络、移动网络)各查一次,最后看旧服务器的访问日志,如果日志还在涨,就说明确实还有流量没切干净。如果三个来源都指向同一批旧答案,那就是某一级的递归缓存还没过期,不是你记录填错了。
写在最后
DNS 解析切换这件事的复杂度,并不在于改一个 IP 有多难,而在于它是一个分布式、异步、带时间窗口的操作。所有看起来"没生效"的问题,最后都能落到一句话上:某个地方还拿着过期答案,而你不知道它在哪儿、还要待多久。
所以我把这次踩的坑压成两句给自己:要切,先降 TTL,然后等;切完,别急着关旧机器。这两句话看着朴素,但它能省掉的那 6 个小时,是实打实的半夜起床和客户的投诉单。你要是正准备迁移,把顺序照着走一遍,问题基本就绕开了。


喜欢
顶
难过
囧
围观
无聊



