DNS主从同步延迟导致部分用户访问不到新IP怎么处理

线上换IP时,最容易被低估的不是业务切换,而是DNS传播。尤其是自建DNS主从架构,主DNS已经改了A记录,自己dig也能看到新IP,但用户侧反馈很割裂:有的人访问正常,有的人还解析到旧IP,有的人直接解析失败。

这种问题表面看像“DNS没生效”,实际要拆开看:主DNS有没有改成功、从DNS有没有同步、递归DNS有没有缓存、用户本地有没有缓存、旧IP是否还能兜底。每一层都可能让用户看到不同结果。

先判断:是主从同步延迟,还是递归缓存没过期

很多现场排障会卡在这里。看到用户还解析到旧IP,就直接怀疑从DNS没同步,其实不一定。DNS链路里至少有三层缓存:权威DNS、递归DNS、本地客户端缓存。

最直接的办法是分别查主DNS、从DNS、公共递归DNS。

查权威DNS时,不要只用默认dig。默认dig走的是系统配置的递归DNS,结果可能已经被缓存。要指定NS服务器查。

示例:

dig @主DNS_IP www.example.com A +noall +answer

dig @从DNS_IP www.example.com A +noall +answer

dig @8.8.8.8 www.example.com A +noall +answer

dig @223.5.5.5 www.example.com A +noall +answer

dig @119.29.29.29 www.example.com A +noall +answer

如果主DNS返回新IP,从DNS返回旧IP,这就是主从同步问题。如果主从都返回新IP,但公共递归DNS还返回旧IP,那多半是TTL缓存还没到期。如果公共递归DNS都新了,只有个别用户旧,那就是本地运营商递归缓存或终端缓存。

实际使用中发现,SOA serial比A记录更关键

Bind、PowerDNS这类权威DNS做主从同步时,从DNS不会盲目同步所有记录,它会看SOA记录里的serial。serial没变,从DNS可能认为zone没有变化。

现场遇到过这种情况:运维在主DNS后台改了A记录,但serial没有正确递增。从DNS日志里能看到它来检查过zone,但判断“不需要更新”。这时主DNS看起来完全正常,从DNS一直旧。

检查方式:

dig @主DNS_IP example.com SOA +noall +answer

dig @从DNS_IP example.com SOA +noall +answer

重点看SOA里的serial,比如:

example.com. 600 IN SOA ns1.example.com. admin.example.com. 2026011503 300 120 1209600 60

这里的2026011503就是serial。主从serial不一致,从DNS还没追上;主从serial一致但A记录不一致,说明zone文件、视图、缓存或加载异常,要看具体DNS软件配置。

主从同步延迟常见位置

DNS NOTIFY没送到

正常主DNS变更zone后,会向从DNS发送DNS NOTIFY。从DNS收到后再发起AXFR或IXFR同步。如果NOTIFY被防火墙挡了,从DNS只能等refresh周期自己来问。

比如SOA里refresh是3600秒,那从DNS可能最多等1小时才检查变化。很多人以为“DNS同步很慢”,其实是NOTIFY没通,只能靠轮询。

需要检查:

主DNS到从DNS的UDP 53是否通;从DNS到主DNS的TCP 53是否通;防火墙、安全组、云防火墙有没有只放了UDP 53忘了TCP 53。

这里补充一点:AXFR大概率走TCP 53,IXFR也可能走TCP。只放UDP 53只能保证普通查询,不代表主从同步一定正常。

allow-transfer或TSIG配置不一致

主DNS通常会限制哪些从DNS可以拉取zone:

allow-transfer { 从DNS_IP; };

如果从DNSIP变了、安全组NAT后源IP变了、TSIG key不一致,从DNS会收到拒绝。表现就是主DNS已经更新,从DNS日志里出现transfer failed、REFUSED、not authoritative、bad key之类信息。

排查时要直接看日志,不要只看控制台:

journalctl -u named -f

tail -f /var/log/named/named.log

PowerDNS也类似,看pdns日志里是否有AXFR denied、NOTIFY failed、serial check failed。

从DNS没reload或zone加载失败

还有一种不明显的问题:从DNS已经拉到了新zone文件,但加载失败。比如zone文件里少了点号、CNAME和A记录冲突、同名记录格式错误。

Bind可以用:

named-checkzone example.com /var/named/slaves/example.com.zone

named-checkconf

如果是动态zone或数据库型DNS,也要确认后端数据库写入成功,别只看前端页面。

换IP前的TTL处理,不是临时抱佛脚

DNS切换前最稳的动作,是提前降低TTL。比如原来TTL是3600秒,计划晚上22:00切IP,最好在当天上午或者前一天把TTL降到60秒或120秒。

如果在切换那一刻才把TTL从3600改成60,已经拿到旧记录的递归DNS不会因为你现在改TTL就立刻清缓存。它仍然可能拿着旧IP用满之前的3600秒。

一个比较常见的时间线可以这样看:

10:00 将www.example.com TTL从3600改为60,并确认主从同步完成。

21:55 检查主DNS、从DNS、主流公共递归DNS的TTL已经接近60。

22:00 将A记录切到新IP,SOA serial递增。

22:01 检查主从serial、A记录一致。

22:05 观察访问日志,新IP是否有流量进入,旧IP是否仍有残留请求。

23:00 旧IP不要急着释放,继续保留兜底。

多说一句,TTL设太低也不是长期好事。60秒适合迁移窗口,平时业务稳定后可以调回300、600或更高。TTL长期过低会增加权威DNS压力,递归侧也不一定完全按你想的执行。

部分用户访问不到新IP,现场怎么止血

旧IP继续保留,做双写或反向代理

切IP时最怕旧IP直接下线。用户递归DNS还没刷新,仍然访问旧IP,这时如果旧IP服务已经停了,就会出现部分用户打不开。

更稳的做法是旧IP保留一段时间,至少覆盖最大TTL和运营商缓存误差。业务简单的话,旧IP继续跑服务;业务复杂的话,旧IP上做Nginx反向代理,把请求转发到新IP。

Nginx兜底示例:

server { listen 80; server_name www.example.com; location / { proxy_pass http://新IP; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }

HTTPS业务要注意证书仍然要在旧IP上可用,否则用户会先卡在TLS握手阶段。

同时发布新旧IP,降低单点切换风险

如果业务允许,可以短时间让A记录返回两个IP:

www.example.com. 60 IN A 旧IP

www.example.com. 60 IN A 新IP

这样一部分用户会打到旧IP,一部分用户打到新IP。等新IP流量稳定后,再移除旧IP。这个方式不适合所有业务,比如强状态连接、会话绑定、本地写盘没有同步的服务,用之前要看应用层是否能承受。

对外提供临时备用域名

有些B端系统、游戏登录器、App配置中心,用户端缓存特别顽固。遇到紧急迁移,可以准备一个备用域名,比如 new-api.example.com,直接指向新IP,用配置下发、公告或客户端热更新绕过老解析链路。

这个动作不优雅,但救急有效。尤其是海外用户访问国内或国内用户访问香港、美国节点时,中间递归DNS行为差异很大,不能只按本地测试结果判断。

主从DNS配置里几个容易忽略的参数

SOA refresh、retry、expire、minimum

SOA里常见字段长这样:

example.com. IN SOA ns1.example.com. admin.example.com. 2026011503 300 120 1209600 60

这些值大概含义是:

serial:zone版本号,主从同步判断变化的核心字段。

refresh:从DNS多久向主DNS检查一次serial。

retry:同步失败后多久重试。

expire:从DNS长期联系不上主DNS时,多久后认为zone失效。

minimum:现在更多用于negative cache,也就是NXDOMAIN这类否定结果缓存时间。

如果refresh设置成3600或7200,NOTIFY又没生效,主从同步延迟就会很明显。生产环境里,常见做法是refresh 300秒,retry 60到120秒,negative cache 60到300秒,看业务对DNS变化的敏感程度。

negative cache也会坑人

实际使用中发现,很多“新域名解析不生效”不是A记录缓存,而是NXDOMAIN缓存。比如用户在记录创建前访问过 test.example.com,当时不存在,递归DNS缓存了NXDOMAIN。后面你添加A记录,用户那边还是可能在negative TTL内继续认为域名不存在。

所以新业务上线前,域名记录要提前创建,不要等服务启动那一刻才加DNS。哪怕先指到维护页IP,也比临时创建要稳。

跨地域业务更要关注权威DNS质量

自建主从DNS在单机房内很容易看起来正常,但跨地域后问题会放大。比如主DNS在香港,从DNS在美国,中间网络抖动,AXFR超时,某些从节点同步落后;再叠加不同运营商递归DNS缓存,用户看到的结果就会很乱。

如果业务本身还涉及云服务器迁移,比如从普通海外节点切到香港CN2、美国精品网或高防节点,建议把DNS切换和服务器切换分开做。先让新服务器跑起来,通过hosts或灰度域名验证,再切DNS。

购买节点时也要看线路和防护场景。比如国内用户访问香港业务,香港综合-C型这类CN2+CMI+CU线路更适合低延迟回国访问;遇到游戏、接口被打、活动页容易被DDoS扫的场景,香港高防-E型这种高防秒解、大陆优化线路更贴近实战。如果你也在找这种云服务器和高防节点,可以看看129云,他们做美国精品网、香港CN2、高防服务器这些场景比较多,客服热线400-9177118可以直接问线路和防护细节。

排障时建议按这个顺序查

查权威NS列表是否正确

先确认域名注册商处配置的NS是不是你当前这批权威DNS。很多迁移事故不是记录没同步,而是用户还在访问旧NS。

命令:

dig example.com NS +trace

看最终返回的NS是否符合预期。再分别查询每台NS:

dig @ns1.example.com www.example.com A +noall +answer

dig @ns2.example.com www.example.com A +noall +answer

dig @ns3.example.com www.example.com A +noall +answer

如果有一台NS还返回旧IP,用户命中它就会异常。DNS不是每次都只问你认为“主”的那台NS,递归DNS会在权威NS之间选择。

查serial是否一致

每台权威NS都查SOA:

dig @ns1.example.com example.com SOA +short

dig @ns2.example.com example.com SOA +short

dig @ns3.example.com example.com SOA +short

serial不一致时,不要急着反复改A记录。应该先修同步链路,确认NOTIFY、AXFR、IXFR、TSIG、allow-transfer都正常。反复改记录只会让版本更乱。

查递归DNS缓存剩余TTL

公共递归DNS返回旧IP时,看TTL还剩多少:

dig @8.8.8.8 www.example.com A

dig @1.1.1.1 www.example.com A

dig @223.5.5.5 www.example.com A

dig @119.29.29.29 www.example.com A

如果TTL还剩几百秒,等它过期就行。如果TTL显示很小但一直不变,可能中间有DNS代理或运营商缓存异常。部分运营商Local DNS会不严格遵守TTL,这种情况只能通过旧IP兜底、备用域名、客户端刷新来缓解。

查业务访问链路,不要只盯DNS

有时候DNS已经新了,但用户访问不到新IP,是新IP侧安全组、WAF、DDoS清洗、源站白名单没放通。DNS只是把用户带到新地址,后面TCP、TLS、HTTP都可能出问题。

检查项可以直接按链路跑:

ping 新IP,看基础连通性,不通不一定代表业务不可用,但能提供参考。

telnet 新IP 80 / 443,确认端口开放。

curl -H "Host: www.example.com" http://新IP/ -I,确认按域名访问能命中正确站点。

openssl s_client -connect 新IP:443 -servername www.example.com,确认SNI和证书没问题。

如果用了高防IP或DDoS清洗,还要确认回源IP、回源端口、源站防火墙白名单。高防节点切换时,经常出现DNS解析到高防IP了,但源站只允许旧高防回源段,导致新链路502。

主从DNS同步的配置建议

Bind主DNS示例

主DNS zone配置示例:

zone "example.com" { type master; file "/var/named/example.com.zone"; allow-transfer { 10.0.0.2; 10.0.0.3; }; also-notify { 10.0.0.2; 10.0.0.3; }; notify yes; };

变更zone后:

named-checkzone example.com /var/named/example.com.zone

rndc reload example.com

rndc notify example.com

如果只是改了zone文件但没有reload,主DNS本身也可能还在用旧数据。这个问题在手工维护zone文件的环境里很常见。

Bind从DNS示例

从DNS配置示例:

zone "example.com" { type slave; masters { 10.0.0.1; }; file "/var/named/slaves/example.com.zone"; };

从DNS上可以手动触发同步:

rndc refresh example.com

rndc retransfer example.com

refresh是检查更新,retransfer是重新传输整个zone。遇到从DNS数据明显异常时,retransfer比反复reload更直接。

切换窗口里怎么观察是否还有旧IP流量

不要只看DNS结果,要看旧IP和新IP两边的访问日志。切换后如果旧IP还有大量请求,说明仍有递归DNS或客户端缓存未更新。

Nginx可以临时加一个单独access_log,记录Host、源IP、User-Agent:

log_format dns_migrate '$remote_addr $time_local $host "$request" $status "$http_user_agent"';

access_log /var/log/nginx/dns_migrate.log dns_migrate;

观察方式:

tail -f /var/log/nginx/dns_migrate.log

awk '{print $1}' /var/log/nginx/dns_migrate.log | sort | uniq -c | sort -nr | head

如果旧IP流量持续来自某些固定出口IP,可能是企业网关、运营商递归DNS、代理网关缓存。B端客户可以让对方刷新DNS缓存,C端用户就只能靠等待和旧IP兜底。

不同故障表现对应的处理动作

| 现象 | 更可能的原因 | 处理动作 |

| 主DNS新IP,从DNS旧IP | SOA serial没递增、NOTIFY失败、AXFR/IXFR失败 | 查serial、日志、TCP 53、allow-transfer、TSIG |

| 所有权威NS都是新IP,公共DNS旧IP | TTL缓存未过期 | 等待TTL,旧IP保留服务 |

| 公共DNS新IP,个别用户旧IP | 运营商递归DNS或本地缓存 | 旧IP兜底,提示刷新DNS,必要时备用域名 |

| 解析到新IP但打不开 | 安全组、防火墙、WAF、高防回源、证书问题 | curl指定Host、检查端口、TLS、源站白名单 |

| 新增子域名提示不存在 | negative cache | 提前创建记录,降低SOA minimum |

减少下次切换事故的做法

变更前做预检

切DNS前,先用hosts把域名指到新IP,从真实客户端访问一遍。不要只在服务器上curl 127.0.0.1,也不要只测IP。很多站点依赖Host、SNI、回调域名、跨域配置,直接访问IP正常不代表按域名访问正常。

预检命令:

curl -H "Host: www.example.com" http://新IP/ -I

curl --resolve www.example.com:443:新IP https://www.example.com/ -I

第二条很有用,它可以不改本机hosts,直接让curl把域名解析到指定IP,同时保留HTTPS SNI。

变更时盯三类指标

DNS侧看主从serial、A记录、TTL。

网络侧看新IP入口流量、旧IP残留流量、TCP连接数。

业务侧看HTTP 5xx、登录成功率、支付回调、API耗时。

DNS切换不是只看dig成功。dig成功只能说明解析链路部分正常,用户能不能完成业务请求,还要看后面的网络和应用。

变更后不要马上释放旧资源

旧IP至少保留一个最大TTL周期,再根据日志看是否还有流量。海外业务、移动网络、企业内网用户多的场景,可以保留24到48小时。成本上多跑一天机器,通常比一批用户访问失败便宜得多。

如果旧IP来自临时服务器,迁移时可以选同区域、同线路的新机器,减少链路变量。比如香港业务从普通线路迁到CN2+CMI+CU,建议先让新旧两边同时在线;美国业务如果面向国内访问,美国精品网-B型这种三网精品线路比普通国际线路更容易控延迟和丢包。线路变化越大,DNS切换窗口越要保守。

遇到已经发生的事故,按这个节奏处理

立刻恢复旧IP服务,或者在旧IP上反代到新IP。用户还解析到旧IP时,这是最快的止血动作。

同时检查所有权威NS的A记录和SOA serial,把不同步的从DNS拉齐。必要时执行rndc retransfer,修复allow-transfer、TSIG、防火墙规则。

确认新IP服务完整可用,包括安全组、WAF、高防回源、HTTPS证书、应用配置。

把TTL临时降到60或120,但不要指望它清掉已经存在的旧缓存。它只影响后续重新查询。

从旧IP日志里观察残留用户量。残留明显下降后,再考虑移除旧IP或关闭反代。

如果域名被企业客户、App客户端、游戏登录器硬编码或长缓存使用,不要频繁来回切。来回切会让不同递归DNS拿到不同版本,现场更难判断。保留一个稳定方向,用旧IP兜底把用户导过去。