你 30 分钟前改了 DNS 记录。站打不开,或者打开看到的还是旧服务器的内容。你不停刷新、等待,跑去 X 上 @ DNS 提供商。几乎每一次,记录其实都是对的——只是还没传播到每个 resolver,或者你自己这台机器还攥着旧答案。
能解释 90% 这类情况的一个事实:传播按记录在你改动之前设好的 TTL(Time To Live)走。如果旧记录的 TTL 是 86400(24 小时),某些 resolver 就会继续返回旧 IP 最长 24 小时——你现在做什么都改变不了。今天调低 TTL,只能加速下一次改动。
诊断铁律:信 dig,别信浏览器。浏览器在 DNS 之上还叠了自己的缓存、HSTS 状态和连接复用,所以它会就「DNS 实际返回了什么」对你撒谎。
一句话总结
- 跑
dig yourdomain.com +short。返回新 IP,说明 DNS 没问题,毛病在本地(缓存、HSTS、CDN)。 - 跑
dig NS yourdomain.com,确认你改的是生效那套 nameserver 上的记录。 - 清你的 OS DNS 缓存和 Chrome 的 host cache(这两个是分开的)。
- 如果
dig @8.8.8.8显示新值、但dig @你的ISP解析器显示旧值,那没什么可修的——等旧 TTL 过期就好。ISP resolver 通常 1–24 小时内追上。
先看你属于哪一类
跑一条命令,然后跳到下面对应的原因。
dig yourdomain.com +short 返回 | 说明 | 跳到 |
|---|---|---|
| 新 IP | DNS 没问题,毛病在本地或下游 | 原因 2(本地缓存)、5(CDN)、6(HSTS) |
| 旧 IP | 某个 resolver 还在缓存旧记录 | 原因 1(旧 TTL)、4(慢 resolver) |
什么都没有 / NXDOMAIN | 记录缺失,或改到了错的 zone | 原因 3(改错提供商) |
一个 Cloudflare anycast IP(如 104.x / 172.67.x) | 记录处于代理状态,这是正常的 | 原因 5(CDN) |
常见原因
按「真正是元凶」的频率从高到低排。
1. 旧 TTL 太高(最常见)
每条记录都有 TTL,告诉 resolver 这个答案能缓存多久。真正起作用的,是你改动那一刻生效的那个值。如果当时是 3600(1 小时)或 86400(24 小时),那就是最坏情况下要等的时长。
怎么判断:
dig +nostats yourdomain.com
;; ANSWER SECTION: 这一行里,名字后面的数字就是这个 resolver 此刻报的 TTL。隔一分钟再跑一次——如果这个数字在往下减,说明该 resolver 给的是缓存副本,倒计时就是它距离重新拉取还剩多少秒。
2. 本地 OS / 浏览器缓存
就算 DNS 已经全球传播完,你自己这台机器在本地缓存 TTL 过期之前,仍然返回旧答案。而且 Chrome 维护着一份和 OS 完全独立的 DNS 缓存,所以经常两边都得清。
怎么判断:终端 dig 返回新值,但浏览器还是加载旧站。
清 OS 缓存:
- macOS:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder - Linux(systemd-resolved,Ubuntu 22.04+/Fedora 33+ 的默认):
sudo resolvectl flush-caches - Windows 11:
ipconfig /flushdns(用管理员身份打开终端)
然后清 Chrome(它有自己的 resolver 缓存,还会复用已建立的 socket):
- 打开
chrome://net-internals/#dns→ 点 Clear host cache。 - 打开
chrome://net-internals/#sockets→ 点 Flush socket pools,免得 Chrome 复用一条连到旧 IP 的旧连接。
3. 改在了错的 DNS 提供商
你有一个 registrar(买域名的地方),可能还有一个单独的 DNS 托管商(Cloudflare、Route 53 等)。只有一套 nameserver 是权威的,由 registrar 的 NS 记录指向哪一套决定。一个常见翻车:你在 registrar 自带的 DNS 面板里改记录,但你的 nameserver 其实指向 Cloudflare——于是你的改动落到了空处。
怎么判断:
dig NS yourdomain.com +short
如果返回的 nameserver(比如 xxx.ns.cloudflare.com)和你刚才改动的那家提供商对不上,那你改的是不生效的那个 zone。
4. 某些 resolver 旧值留得更久
公共 resolver——Google 8.8.8.8、Cloudflare 1.1.1.1、Quad9 9.9.9.9——一般都老老实实守 TTL。ISP 和企业 resolver 有时会把 TTL 往上取整或套一个最小缓存时间,于是滞后。这里没什么技术手段,只能等。
怎么判断——直接逐个查多个 resolver:
dig @8.8.8.8 yourdomain.com +short
dig @1.1.1.1 yourdomain.com +short
dig @9.9.9.9 yourdomain.com +short
如果三个都返回新值、但个别用户仍然打不开,那滞后的就是他们的本地或 ISP DNS。
5. 前置 CDN / 代理返回了缓存响应
如果 DNS 指向 CDN(Cloudflare 橙云代理、Fastly、CloudFront),访客打到的是 CDN 的缓存,不是你的源站。DNS 改对了不会清掉 CDN 缓存——那是另一件事。
怎么判断:对比「走 CDN」和「直连源站 IP」两种请求。
curl -sI https://yourdomain.com # 走 CDN
curl -sI --resolve yourdomain.com:443:ORIGIN_IP https://yourdomain.com # 绕开 CDN
如果 CDN 响应是旧的、源站响应是新的,就去清 CDN 缓存。注意:在 Cloudflare 上,被代理(橙云)的记录永远报一个固定的 Auto TTL 300 秒,公网解析出来的是 Cloudflare 的 anycast IP,不是你源站的 IP——所以 dig 不会显示你服务器的真实 IP。这是正常的,不是 bug。
6. 浏览器的 HSTS pinning
如果旧站发过 Strict-Transport-Security 头(尤其带 includeSubDomains 和很长的 max-age),浏览器会强制对它当前解析到的地址走 HTTPS,并且拒绝绕过证书不匹配。你会看到 NET::ERR_CERT_AUTHORITY_INVALID 或「您的连接不是私密连接」,连「仍要继续」的链接都没有。
怎么判断和修复:打开 chrome://net-internals/#hsts,翻到 Delete domain security policies,输入域名,点 Delete,重启 Chrome。如果同一个域名换个浏览器能正常打开,那元凶就是 HSTS 状态。
最短修复路径
第 1 步:用 dig 验证,不用浏览器
dig yourdomain.com +short
应该返回新 IP 或目标。返回了新值,就说明 DNS 本身在正常传播,问题在下游(本地缓存、HSTS 或 CDN),直接跳到第 4–5 步。
第 2 步:多 resolver、多区域测
用 dnschecker.org,它会从全球几十个地点的 resolver 发起查询。如果大多数显示新值、个别还显示旧值,那就是单纯还在传播中——接着等就好,别再反复改记录。
第 3 步:确认改的是生效的 DNS 提供商
dig NS yourdomain.com +short
列出的 nameserver 就是权威的那套。在它们那里改记录,别在别处改。
第 4 步:清本地 + 浏览器 DNS
确认全球传播完之后:
# macOS
sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder
# Linux (systemd-resolved)
sudo resolvectl flush-caches
# Windows 11(管理员终端)
ipconfig /flushdns
然后在 chrome://net-internals/#dns 清 Chrome(Clear host cache),并在 chrome://net-internals/#sockets 点 Flush socket pools。
第 5 步:为下一次改动提前降 TTL
在 DNS 提供商里,计划改动至少 24 小时前把这条记录的 TTL 设成 300(5 分钟)。到改动那天,旧的缓存条目 5 分钟内就过期,传播体感几乎是瞬时的。2026 年 6 月的各家情况:
| 提供商 | 默认/Auto TTL | 可手动设的最低 TTL | 备注 |
|---|---|---|---|
| Cloudflare(仅 DNS) | Auto = 300 秒 | 60 秒(非 Enterprise)、30 秒(Enterprise) | 范围 60–86400 秒,见 Cloudflare TTL 文档 |
| Cloudflare(已代理) | Auto = 300 秒,固定 | 不可改 | 公网解析的是 Cloudflare 的 anycast IP |
| AWS Route 53 | 无默认值——自己填 | 可填 0 秒 | 常见做法是 300 秒 |
| Namecheap | Automatic(常为 ~1800 秒) | 60 秒 | 「Automatic」会藏住真实数字,迁移前手动填个明确的低值 |
| GoDaddy | 1 小时(3600 秒) | 600 秒(10 分钟) | 任何迁移前都要提前调低 |
第 6 步:ISP resolver 就只能等
如果 dig @8.8.8.8 显示新值、但某用户的 ISP DNS 显示旧值,这里没有技术杠杆可拉——那是一台你管不到的服务器上的缓存。ISP resolver 一般 1–24 小时内追上,上限就是旧记录的 TTL。
怎么确认真的修好了
下面三条都成立,才算完成:
- 权威答案正确。
dig +short yourdomain.com @$(dig +short NS yourdomain.com | head -1)返回新 IP。直接查权威 nameserver 会绕开一切缓存,所以这是最可信的源头。 - 公共 resolver 也一致。
dig @8.8.8.8 yourdomain.com +short和dig @1.1.1.1 yourdomain.com +short都返回新 IP。 - 你自己这台机器也看到了。 清完缓存后,
dig yourdomain.com +short(不带@服务器,走你配置的 resolver)返回新 IP,并且用无痕窗口能打开新站。用无痕是为了让旧站的 service worker 或 HTTP 缓存盖不住结果。
如果第 1 条对、第 2 条还滞后,那只是在等传播——没坏。如果第 2 条对、第 3 条还滞后,那滞后的就是你的本地或 ISP 缓存。
预防建议
- 任何计划内的 DNS 或迁移改动前,至少 24 小时把 TTL 降到
300。 - 改记录前,永远先用
dig NS验证权威 nameserver。 - 用
dig验证 DNS 状态,绝不靠浏览器。 - 改源站 DNS 时,把清 CDN 缓存当作单独的一步去做。
- 把「谁持有你的权威 zone」写下来(仓库 README 或 runbook 里一行就够),免得排障时队友改错面板。
常见问题
DNS 传播到底要多久?
取决于旧记录上的 TTL,而不是某个固定的全球计时器。TTL 是 300 秒时,多数 resolver 5 分钟内刷新;TTL 是 86400 秒(24 小时)时,最坏要等 24 小时。8.8.8.8、1.1.1.1 这类公共 resolver 对 TTL 守得很紧;部分 ISP resolver 会滞后。
dig 显示新 IP,但浏览器还是加载旧站,为什么?
浏览器缓存和 DNS 是分开的。先清 OS 缓存,再在 chrome://net-internals/#dns 清 Chrome 的 host cache,并在 chrome://net-internals/#sockets 点 Flush socket pools。如果遇到无法绕过的证书错误,再去 chrome://net-internals/#hsts 清 HSTS。
我改了记录,但 dig NS 显示的是一家我没动过的提供商,怎么回事?
你改在了错的(不生效的)zone。dig NS 列出的那家才是权威的。到那家提供商的 DNS 面板里重新改一遍。
我的 Cloudflare 记录是代理状态,dig 显示的是 Cloudflare 的 IP 不是我的服务器,坏了吗?
没坏。被代理(橙云)的记录按设计就解析到 Cloudflare 的 anycast IP,并且永远报 300 秒的 TTL。想看到你的源站,临时把记录切成「仅 DNS」(灰云),或者用 curl --resolve 直接查源站。
我能强制全世界所有 resolver 丢掉旧记录吗? 不能。你管不到的 resolver 上的缓存,你清不了。你唯一的控制点,是改动之前设的那个 TTL。改完之后还要等多久,由旧 TTL 决定。