DNS 改了没生效:一份系统化的排查流程

「我改了 DNS 记录,但访问的还是旧地址」——这个问题几乎每个人都遇到过。按固定顺序排查,五分钟就能定位。

一、先理解有四层缓存

bash
你的电脑 → 本地 DNS 缓存 → 路由器 → ISP/公共 DNS → 权威 DNS(Cloudflare 等)

任何一层存了旧值,你看到的就还是旧地址。所以排查方向是从下往上逐层确认

二、第一层:本地缓存

bash
# 用不同的公共 DNS 对比
for ns in 1.1.1.1 8.8.8.8 223.5.5.5; do
  echo -n "$ns → "; dig @$ns +short www.bzii.cn A;
done

判断:

  • 本地和其他 DNS 结果都不一样 → 本地缓存问题;
  • 所有 DNS 结果都一样(都是旧值) → 问题在上层。

解法:清缓存(命令见下),然后换浏览器无痕窗口再测(浏览器自己也缓存)。

bash
sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder  # macOS
sudo resolvectl flush-caches                                       # Linux
ipconfig /flushdns                                                 # Windows
# Chrome: chrome://net-internals/#dns → Clear host cache

三、第二层:权威 DNS 改对了吗

这是最关键的一步——先确认你的修改是否真的保存了。

bash
# 1. 查出权威服务器
dig +short www.bzii.cn NS
# lola.ns.cloudflare.com.
# tim.ns.cloudflare.com.

# 2. 直接问权威服务器
dig @lola.ns.cloudflare.com www.bzii.cn A +short

判断:

  • 权威服务器返回新值 → 配置没问题,只是传播需要时间;
  • 权威服务器返回旧值或空 → 你的修改没生效,回去检查控制台。

四、第三层:改的地方对吗

最常见的几个低级错误:

错误说明
改了 A 记录但访问的是 www主机记录要区分 @www
改了 www 但访问根域同上
在错误的 DNS 服务商改域名的 NS 指向谁,就要在哪改
有多条同名记录可能只改了一条
记录被禁用(灰色云/暂停)检查状态开关
bash
# 确认 NS 到底指向谁
dig +short www.bzii.cn NS
# 然后去那个服务商的控制台改

# 查所有同名记录
dig www.bzii.cn A | grep -A10 "ANSWER SECTION"

「在 A 平台改了半天没反应,其实 NS 指向的是 B 平台」——这个坑我见过太多次。

五、第四层:TTL 与传播时间

bash
# 看当前 TTL
dig www.bzii.cn A | grep -A2 "ANSWER SECTION"
# www.bzii.cn.  300  IN  A  1.2.3.4
#              ↑ 还剩 300 秒

已缓存旧值的 DNS 服务器要等 TTL 到期才会重新查询。

TTL 设置传播时间
3600(1 小时)最多 1 小时
1800最多 30 分钟
300(5 分钟)最多 5 分钟
Cloudflare 自动通常 300s

所以重要变更前先把 TTL 调低,这是唯一的加速手段。改完后:

bash
# 持续观察,看什么时候变
watch -n 15 "dig +short www.bzii.cn A"

# 看全球生效情况
# 打开 dnschecker.org 输入域名

六、特殊原因:CDN 代理

Cloudflare 开橙色云时,dig 返回的是 Cloudflare 的 IP,不是你的源站 IP。这是正常的。

bash
dig +short www.bzii.cn A
# 104.21.x.x   ← Cloudflare 的 IP

# 想看源站 IP,用灰色云(DNS only)或查子域名
dig +short origin.bzii.cn A

所以「改了解析但没变」有时其实是:变了,只是你看到的都是 CF 的 IP。判断方法是看页面内容或用 curl 看响应头。

bash
curl -sI https://www.bzii.cn | grep -i "cf-ray\|server"

七、特殊原因:本地 hosts 文件

如果你为了测试改过 hosts,会一直生效:

bash
cat /etc/hosts
# Windows: C:\Windows\System32\drivers\etc\hosts

# 检查有没有指向旧 IP 的条目
grep baize /etc/hosts

八、特殊原因:VPN / 代理

VPN、公司网络、某些代理会走自己的 DNS,导致结果和预期不同。

bash
# 看当前用的 DNS 是什么
cat /etc/resolv.conf
resolvectl status

# 关掉 VPN 再测一次

九、排查清单(照着走)

bash
# 1. 本地缓存清了吗
sudo resolvectl flush-caches

# 2. 多个公共 DNS 对比
for ns in 1.1.1.1 8.8.8.8 223.5.5.5; do dig @$ns +short www.bzii.cn A; done

# 3. 权威服务器怎么说
dig @$(dig +short www.bzii.cn NS | head -1) www.bzii.cn A +short

# 4. NS 指向对吗
dig +short www.bzii.cn NS

# 5. hosts 里有吗
grep baize /etc/hosts

# 6. 全球生效了吗
# dnschecker.org

# 7. TTL 是多少
dig www.bzii.cn A | grep -A2 "ANSWER"

十、真正紧急时怎么办

如果站点挂了等不及传播:

  1. 临时改本地 hosts 指向新 IP,先自己能用;
  2. 如果旧服务器还在,让旧服务器做反向代理转发到新服务器;
  3. 或者临时用另一个已生效的子域名。

DNS 传播没有「强制刷新」按钮。唯一能做的是提前降 TTL,然后耐心等。