
搞了这么多年运维我印象最深的一次DNS排查是在给一家小公司做网站迁移。后台A记录明明已经改成新服务器IP客户那边却一直打开老页面。我手工把递归链路问了个遍最后发现问题就出在TTL上这条域名之前的缓存时间是86400秒也就是整整一天。这个场景太典型了很多朋友做完服务器切换、域名搬家之后都会卡在同一个问题上——改了DNS记录到底什么时候才生效怎么有人一小时就看到了新页面有人第二天还在访问旧IP。今天干脆把整条链路讲清楚从域名解析的过程、TTL机制到改A记录、换NS服务商的实操顺序最后再给一份排查速查表希望能帮大家少踩几个坑。1. DNS 到底在干什么一次解析请求的完整旅程1.1 浏览器输入域名后第一步发生在哪先别急着聊记录、聊TTL得把DNS解析这件事本身弄明白。DNS全称是Domain Name System翻译过来就是域名系统它的核心功能特别朴素把人类好记的域名比如 example.com翻译成机器能识别的IP地址。你在浏览器地址栏敲下域名敲回车的那一瞬间浏览器干的不是直接去问“根服务器”而是先查自己手头的三样东西浏览器自身的DNS缓存。Chrome、Edge这些浏览器会按规则缓存一部分解析结果缓存时间远低于系统TTL。操作系统层的DNS缓存。Windows、macOS、Linux都会在本地缓存解析结果方便二次访问更快。hosts文件。这是最传统、优先级最高的本地域名映射表只要hosts里有对应条目DNS协议根本不参与。这三层都查不到系统才会把解析请求交给自己网络配置里写的DNS服务器。这台DNS服务器可能是路由器通过DHCP下发的也可能是在电脑、服务器的网卡配置里手动指定的。很多人一听“配置DNS”就头疼其实原理就一句话系统会找一台“替你跑腿”的服务器让它去帮你问清楚某个域名到底对应哪个IP。日常遇到“电脑能上QQ但打不开网页”十有八九就是这台服务器配置出了问题。1.2 从递归服务器到权威服务器的“传话”过程你配置的那台DNS服务器专业术语叫递归解析服务器。它替客户端跑腿干的是“递归查询”的活。举个例子请求解析 www.example.com 的时候递归服务器大概要做这么几件事先问一个“根服务器”你知道 .com 顶级域的服务器在哪吗根服务器不负责具体域名但它知道 .com 域由哪些顶级域服务器管理。拿到 .com 顶级域服务器地址后再问它example.com 这个域名的权威服务器是哪几台顶级域服务器会返回 example.com 的NS记录。拿到NS记录后再去问 example.com 的权威DNS服务器www 这个主机名的A记录或CNAME到底是什么权威服务器给出最终答案。这里有个细节客户端到递归服务器之间是“递归查询”递归服务器到根、顶级域、权威服务器之间通常是“迭代查询”每一层都返回一个指引然后递归服务器再顺着指引往下问。整个过程快得离谱通常只需要几十毫秒。递归服务器跑完一趟不会白跑会把查询结果连同TTL一起缓存下来。这个缓存动作就是后面所有“生效时间”故事的起点。1.3 常见的DNS记录类型别只知道A记录聊生效时间之前先得认识一下我们改的到底是什么。DNS里有很多记录类型日常用得最多的是这么几种记录类型作用典型使用场景A域名指向IPv4地址网站、接口服务指向服务器AAAA域名指向IPv6地址支持IPv6的站点CNAME域名别名指向另一个域名把 www 指向主域名MX邮件交换记录指定邮件服务器企业邮箱收发信TXT任意文本常用于验证SPF、DKIM、域名归属验证NS指定该域名的权威DNS服务器域名托管给哪家解析SOA记录区域版本信息和主权威服务器权威服务器同步判断SRV指定服务所在主机和端口企业即时通信等场景A记录和CNAME是最容易搞混的。A记录直接给IPCNAME只是告诉你“这个域名其实是另一个域名的别名”紧接着还要再解析一次目标域名。CNAME的好处是改目标域名时不用动所有子域名坏处是多一层查询在极端情况下会拉长解析链路。能用A记录尽量用A记录这是个经验之谈。SOA记录里的Serial、Refresh、MTTL这些字段在排查解析不同步时特别有用。尤其是SOA里的Minimum字段它决定了“查询不存在的记录”时负缓存能缓存多久。这个坑放到后面“新增域名不生效”的环节细说。2. 改了记录之后为什么要等“那么久”2.1 TTL 才是决定生效时间的关键变量TTL全称Time To Live翻译过来就是生存时间单位是秒。DNS协议里每一条解析记录都给查询者附带一个TTL值意思是“这条记录你最多可以在缓存里保存多少秒”。假设修改前example.com 这条A记录返回的TTL是86400也就是24小时。你把IP改成新地址后本机往回看运营商递归服务器手里还攥着旧IP而且它的缓存还没过期它就不会去问权威服务器要新数据而是直接把旧IP甩给所有来问的客户端。也就是说TTL是“旧数据还能存活多长时间”而不是“修改后多久生效”。修改前TTL是86400改完后最坏情况下要等86400秒旧数据才会被递归服务器丢弃然后重新回到权威服务器拿新IP。这个“最坏情况”在互联网上每天都在发生尤其是那些曾经把TTL设成1天、甚至7天的老站点。我见过最夸张的一个客户A记录TTL设置成6048007天。你把记录改得再快旧IP也会在全球各地缓存里多存活一周。2.2 生效时间不是简单数秒数还有这些隐藏缓存TTL只是决定生效时间的一个因素实际上还有好几层缓存叠加在一起浏览器缓存。Chrome缓存DNS默认60秒左右不是特别夸张但会影响你“自己看是否生效”。操作系统缓存。Windows DNS Client服务默认会把成功解析结果缓存一段时间时间按TTL来但有时也会保留。hosts文件。如果机器里hosts写死了旧IP无论权威服务器怎么改这机器永远看到旧IP。局域网路由器和防火墙缓存。很多家用、企业级路由器会缓存DNS结果华三、锐捷这些设备本身也可能有DNS代理功能开启后内网终端查询就走设备缓存设备不刷新终端永远拿旧结果。上级递归服务器缓存。运营商、公共DNS服务商各自的缓存策略不同有的严格执行TTL有的会自作聪明“最小化TTL”导致生效时间比理论值更长。还有一个经常被忽略的点修改NS记录换DNS服务商时生效时间不是看你的新DNS服务商响应多快而是看旧NS记录的TTL以及域名注册局更新父区域信息的速度。父区域更新可能只需要几分钟也可能拖上一两个小时。如果新旧服务商的权威记录内容有差异就会出现“一部分人访问到旧服务一部分人访问到新服务”的过渡状态。2.3 正确的等待时间估算方式日常我们说得最多的是“改完记录一般几分钟到24小时生效”这个说法很模糊。具体怎么估算其实有一个很实用的操作套路我称为“提前降TTL”在正式修改记录之前的足够长时间先把TTL从默认的3600或86400降到300秒。等一个完整的旧TTL周期过去确保全球各地递归服务器里的旧缓存都过期。此时再正式修改A记录、CNAME或MX记录。修改完成并验证后把TTL调回正常值。这里的关键是第二步。比如你原来TTL是86400今天就改成300秒但全球各地还有大量缓存拿着86400的旧TTL在数秒它们可能要到明天才会回来重新查询。T恤降TTL只是“把下一次查询结果的生命周期缩短”不是“立刻清空全世界缓存”。正确的估算公式是最大生效时间 ≈ 当前各层缓存剩余TTL的最大值 权威服务器修改完成的传播时间。所以真要给客户承诺我会说“保守起见按你修改前TTL的完整长度来预估”。这也是为什么运维老手改DNS记录时永远提前一天做准备工作而不是等到业务高峰期才手忙脚乱在控制台里点保存。3. 改A记录、换DNS服务商时我的实操流程3.1 修改A/CNAME记录的完整操作顺序先看一个最常见的场景网站从旧服务器迁到新服务器需要把A记录里的IP地址改掉。我建议按这个顺序操作能少踩很多坑第一步查当前TTL。用一条命令看dig example.com A noall answer返回结果里最后一列数字就是TTL值如果显示86400代表还能缓存一天。第二步如果时间允许先在DNS服务商控制台把TTL改成300秒然后等至少一个原TTL周期。这一步是为了让全球递归服务器提前拿到“短寿命”的新记录。第三步TTL生效后再在控制台把A记录的目标IP改成新服务器IP保存。第四步立刻验证权威服务器是否已经返回新值dig example.com A 223.5.5.5 noall answer用指定一台公共递归DNS如果它返回的是新IP说明权威侧已生效。也可以直接指定你的DNS服务商提供的权威服务器地址查询更快。第五步清掉本地DNS缓存。Windows命令是ipconfig /flushdnsmacOS命令是sudo dscacheutil -flushcache sudo killall -HUP mDNSResponderLinux不同发行版命令不一样CentOS系可以用systemd-resolve --flush-caches新版systemd环境也可以看缓存统计resolvectl statistics第六步用多个渠道观察。比如用第三方在线拨测工具看不同地区查询结果等所有地区都返回新IP再把TTL调回3600或86400。这里有个最容易忽略的细节如果域名下同时配置了A记录、CNAME、MX、TXT一定要确认修改A记录不会影响到邮件服务。很多企业域名把MX和A做在同一个域名上改A记录改错了东家邮件服务跟着遭殃。3.2 换NS/换DNS服务商最容易踩的坑比改A记录更麻烦的是换NS也就是把整个域名的解析托管从一家服务商迁到另一家。很多人上来就把注册商那里的NS记录改了结果新服务商那边记录还没配齐域名全线解析失败。正确顺序应该是在新DNS服务商里把原服务商的所有记录完整复制一份包括A、AAAA、CNAME、MX、TXT、SRV等最好连TTL都保持一致。确认新服务商正常工作。可以通过dig example.com SOA 新服务商NS地址查看SOA记录是否能返回。再到域名注册商控制台把NS记录改成新服务商提供的NS主机名。记住一个关键点改NS后新的解析是否生效取决于旧NS记录在各地缓存的TTL以及域名注册局同步父区域的速度。不是说注册商页面显示“已修改”全世界就立刻用了。还有一个特别容易翻车的点叫“胶水记录”Glue Record。如果你的域名自定义NS主机名恰好是这个域名本身比如 example.com 的NS是 ns1.example.com那么解析 example.com 时会出现一个“先有鸡还是先有蛋”的循环要知道example.com的NS地址又得先解析example.com的NS主机名。这种情况必须在域名注册商那里给 ns1.example.com 添加A记录让顶级的父区域直接把胶水记录带上。很多人第一次自建DNS服务器时就在这里卡了很久。另外切换NS期间尽量不要同时改记录内容。比如你既换了NS又把A记录IP改了等于把两个变量同时引入系统真出了问题很难定位到底是谁导致的。稳妥做法是先只换NS等全链路稳定后再单独改A记录。3.3 内网环境里的DNS代理和自动获取问题排查企业网络时我遇到最多的不是公网TTL问题而是内网设备自己“作妖”。比如华三防火墙默认可能开启DNS代理功能。开启后内网终端的DNS查询会被防火墙接管防火墙替你向上游查询并把结果缓存。如果你修改了某个域名解析内网终端该查的一直是防火墙的缓存你自己在电脑上清一百遍缓存也没用。遇到这种情况要么去防火墙管理界面关闭DNS代理让终端直接使用上游DNS要么把防火墙缓存时间调短。路由器的DNS自动获取也是个常见坑。锐捷、华三这类设备默认从运营商WAN口自动获取DNS表面上很省心但运营商DNS偶发抽风或者是换过宽带线路后路由器的DNS还残留着旧的运营商地址内网解析慢、解析不到的问题就来了。我的习惯是登录路由器管理后台在WAN口设置里把DNS改成手动指定填写公共DNS114.114.114.114、223.5.5.5、119.29.29.29都可以。还有Linux服务器上修改DNS后重启就还原也是高频问题。原因一般是/etc/resolv.conf被NetworkManager、systemd-resolved或DHCP客户端接管了。如果你在文件里手动改了DNS重启网络服务或重启机器后又被覆盖回自动获取的值。长期固定DNS的做法是修改网卡配置文件或systemd-resolved的配置而不是只改resolv.conf。这个话题展开能写另一篇长文这里先提醒一句千万别只改resolv.conf就以为完事了。4. 排查实战三分钟定位还没生效的原因4.1 分清递归缓存与权威返回改了记录后最核心的判断标准是权威服务器返回的是新记录但某些递归节点还在用旧缓存。用一眼能看明白的方式排查第一步查权威服务器视角。先确定你的域名权威NS是哪台dig example.com NS noall answer拿到NS地址后直接用这台权威服务器解析dig example.com A ns1.你的服务商.com noall answer如果返回新IP说明权威侧没问题问题出在下游缓存。第二步查递归服务器视角。用公共DNS递归节点查dig example.com A 114.114.114.114 noall answer dig example.com A 223.5.5.5 noall answer如果返回旧IP说明这台递归节点的缓存还没过期。第三步直接看全链路dig example.com A trace它会从根服务器一路追踪到权威服务器你能看到每一层返回的NS和结果定位到底哪一跳有问题。判断“有没有生效”永远不要只看本机一条nslookup就下结论。本机清完缓存有可能立刻拿到新IP但其他地区用户还得继续等。我一般会用多个省份的拨测工具看分布确认全国甚至全球都切换到新IP之后才敢说“生效完成”。4.2 常见问题速查表整理一份实战中反复遇到的现象表方便收藏现象可能原因排查/解决办法本机始终解析到旧IP浏览器、系统或hosts缓存先查hosts再清浏览器缓存最后flushdns指定公共DNS查询正常默认DNS异常路由器或运营商递归缓存重启路由器/光猫或在路由器和终端手动指定公共DNS新增域名/记录一直不生效之前“不存在的记录”被负缓存查看SOA中的Minimum值等负缓存过期删除记录后仍能访问负缓存或CNAME链上的次级记录用dig trace查CNAME目标是否已删干净不同地区解析结果不一致智能解析/地域DNS查阅权威服务商的分线路配置确认是否故意为之Linux改resolv.conf重启还原DHCP或NetworkManager覆盖修改网卡配置文件或networkd配置内网所有终端解析慢路由器/防火墙开启DNS代理关闭DNS代理手动固定WAN口DNS4.3 几个常见的认知误区第一个误区清完本地DNS缓存全世界都会跟着变。这可能是最大的误会。ipconfig /flushdns只能清掉你眼前这台机器的缓存运营商递归服务器、其他省市用户的浏览器缓存根本不受影响。第二个误区我把TTL改成300秒了所以修改记录马上就生效。改TTL只是给后续查询的新记录一个较短“保质期”之前已经被缓存的旧记录生命周期还是按旧TTL算。第三个误区用nslookup看到新IP就代表生效完成。本机缓存清掉后查一次只能代表这台机器和它使用的递归服务器拿的是新值不代表全部节点都同步。第四个误区删除DNS记录用户立刻就不能访问了。实际上已经被递归缓存了的记录在缓存过期之前依然能继续被用户拿到。想快速让某个域名完全“消失”只能等所有旧缓存到期或者保留解析但把目标指向一个明确拒绝服务的地址。第五个误区企业内网自建DNS服务一劳永逸。自建DNS确实灵活比如Windows Server 2016里装好DNS角色后可以建内网区域、配转发器但你必须同时管理好缓存策略和转发目标。之前见过一个单位自建DNS转发器填了一个经常超时的上游地址结果内网解析忽快忽慢改成多个公共DNS后立刻就好了。4.4 我这些年在DNS上养成的三个习惯最后分享几个实际养成的操作习惯谈不上高科技但在关键时刻能救命。一是重大变更前先降TTL。凡是计划内的服务器迁移、域名切换我至少提前一天把TTL从默认值降到300秒。宁愿让解析压力大一点也好过切换后等一天半天的旧缓存。二是切完记录后先验证权威再等缓存。我不会盯着控制台页面发呆而是直接dig权威服务器确认新记录已经生效然后记录下当前时间按旧TTL算出预估全量生效时间再设置一个定时任务或闹钟到点之后用多地拨测确认。三是紧急情况下别慌着“刷新DNS”用旧服务器做过渡。真遇到必须立刻切换又不能等TTL的场景我会在旧IP的服务器上配置一个临时的反向代理或HTTP转发把依然访问旧IP的用户301到新地址去。这样旧缓存没到期之前用户也能通过旧服务器跳到新页面体验基本无损。DNS这件事本身不复杂但牵扯的节点太多任何一个环节的缓存都可能让修改“看起来没生效”。搞懂递归、权威、TTL这三件事再配上一套规范的变更流程绝大部分解析问题都能有理有据地解决不用再干等着拍脑袋。