DNS 解析也会被缓存:为什么刚换的出口,几小时还没生效
DNS 解析也会被缓存:为什么刚换的出口,几小时还没生效
前几天有个场景挺典型:某条对外调用的目标域名做了切换,新的解析记录已经改了,运维那边查权威服务器也确认生效了。可我们自己的服务跑了快两个小时,流量还打在老地址上,新地址一点动静都没有。第一时间怀疑是服务端没刷新,后来才反应过来,问题卡在"谁在缓存这条域名记录"。
很多人以为改了 DNS 就全网立刻生效,实际情况是,域名解析结果从权威服务器到你真正发出请求,中间可能经过好几层缓存,每一层都按自己的时钟在计时。这篇把这条路径捋一遍,下次遇到"改了没生效",你心里有张图,知道该去哪一层查。
一、TTL:缓存的"保质期"
每条 DNS 记录都带一个 TTL(Time To Live),单位是秒。它的意思很直白:这条记录你可以放心缓存多久。
比如 TTL 设的是 300 秒,那任何一层缓存拿到记录后,最多记 5 分钟,过了就重新去查。如果你的 TTL 是 86400,那就意味着改了记录之后,已经拿到结果的人最长可能一天都不来问第二次。
所以"改了没生效"的第一个原因,往往是 TTL 太大。改之前没调小,改完之后旧的记录还在各处待着,不到期不走。很多团队的标准操作是:计划切换前,先把 TTL 调小(比如 60 秒),等切换窗口过了、新地址稳定了,再调回去。
二、缓存不止一层
第二个容易忽略的点:解析结果不是只缓存一次。从你的代码到最终目标,至少经过这几道:
- 操作系统缓存:本机解析过一次,短时间内再问直接给老答案。
- 递归解析器缓存:你用的公共解析服务(比如运营商的、公共 DNS)也会存一份,全小区的请求都从它这儿取。
- 应用层缓存:不少 HTTP 客户端、连接池会自己缓存域名对应的地址,甚至维持长连接不重新解析。
任何一层没过期,你看到的就是"老地址还在用"。这也是为什么同样一个域名,你在本机 ping 已经变了,服务里却还是旧的——两边的缓存时钟根本不同步。
三、怎么验证"到底解析到了哪"
排查时别只信代码里的配置,直接看每一层实际拿到的答案。
命令行里最常用的是带 TTL 查询,能看到记录还能活多久:
dig +noall +answer example.com
# 输出里有一列就是 TTL,数字在减少说明是缓存中的副本
nslookup -type=A example.com
代码侧如果想避开系统缓存、强制拿到最新,可以指定一个不走本地缓存的解析器,或者临时缩短客户端缓存时间。Python 里常见的做法是控制 HTTP 客户端的解析缓存行为,或者干脆在切换窗口内重启一遍相关进程,把内存里的旧记录清掉。
四、一个容易被忽略的坑:长连接不重新解析
还有一个坑比 TTL 更隐蔽。如果你的调用维持着长连接,连接建立时解析了一次,之后这条连接一直复用,域名背后的地址换了,这条老连接根本不会去重新解析。结果就是:DNS 明明全网都更新了,你的流量还在老连接上跑。
这类问题的解法通常不是等,而是主动让连接池滚动重建——比如分批重启、降低连接最大存活时间、或者在切换前后主动摘掉老连接。只调 DNS 是不够的,得让"连"也跟着动。
写在最后
"改了 DNS 没生效"几乎从来不是改错了,而是某层缓存还在它的 TTL 里睡觉。记住三件事:切换前先把 TTL 调小;排查时逐层用 dig 看实际拿到的记录和剩余时间;长连接场景下,光改解析不够,连接也得滚动重建。把这三点串起来,大部分"几小时不生效"的焦虑都能省掉。
本文为原创技术分享,涉及的网络编程思路仅供学习与合法用途参考。请遵守相关法律法规,勿将技术用于任何违规场景。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)