访问一个网站,浏览器要先把这个域名翻译成 IP 地址,这个翻译过程就是 DNS 解析。听起来简单,但解析过程里藏着一组容易混淆的概念:递归查询和迭代查询。它们是谁在问谁、问了几个来回、缓存在哪一层、TTL 怎么影响更新生效速度,直接关系到"域名改了多久才生效""为什么解析忽快忽慢""为什么本地能通外地不通"。
这篇文章把两种查询方式的区别、完整的解析链路、缓存与 TTL、根提示和 glue 记录讲清楚,并用 dig +trace 把整个过程演示一遍。读完你能自己判断解析卡在哪一环、该找哪一层排查。
一、先理清 DNS 的角色
DNS 是一套分布式的数据库,把域名映射到 IP。参与解析的角色主要有:
- Stub 解析器(客户端):操作系统里的解析器,就是"帮本机发 DNS 查询的那部分"。它只负责把请求发出去。
- 递归解析器(Recursive Resolver):通常就是运营商或公共 DNS(如 8.8.8.8、223.5.5.5),也叫 Local DNS。它替客户端把查询"查到底",最后返回最终答案。
- 根域名服务器(Root):全球 13 组,知道所有顶级域(如 .com、.cn)的服务器地址。
- 顶级域服务器(TLD):管理某个后缀(如 .com),知道该域下权威服务器的地址。
- 权威域名服务器(Authoritative):真正保存某个域名解析记录(A、CNAME、MX 等)的服务器,由域名持有者配置。
理解了这些角色,"递归"和"迭代"就好讲了:递归是"我不管过程,你给我最终答案";迭代是"你告诉我下一步该问谁,我自己接着问"。
二、递归查询:替客户端查到底
递归查询发生在客户端 → 递归解析器之间。客户端发一个查询,比如"www.example.com 的 A 记录是多少",并且带 RD(Recursion Desired)标志,意思是"请帮我查到底"。
递归解析器收到后,承担全部责任:如果自己缓存里有答案,直接返回;没有,就替客户端去问根、问顶级域、问权威,一路问到答案为止,最后把结果回给客户端。整个过程对客户端是透明的——客户端只发一次请求,收到一个答案。
这就是为什么你 dig www.example.com 只看到一次请求,背后却可能有七八次网络往返。默认的 dig 请求就是递归查询(RD 位为 1)。
三、迭代查询:一层一层问下去
迭代查询发生在递归解析器 → 各级权威服务器之间。递归解析器不会要求根服务器"帮我查到底",而是问"www.example.com 的地址是多少",根服务器回答"我不知道,但 .com 的服务器地址是这些,你去问它",然后解析器再去问 .com 的 TLD 服务器,得到的又是"你去问 example.com 的权威服务器",最后问到权威服务器才拿到最终 IP。
每一级只告诉你"下一步找谁",这就是迭代。查询的真正"苦力活"由递归解析器承担,而不是客户端。
四、一次完整解析的链路
把两者串起来,用户访问 www.example.com 的完整流程大致是:
- 客户端查本地缓存(浏览器缓存、hosts、系统 DNS 缓存),命中则直接返回。
- 未命中,客户端向配置的递归解析器发递归查询(RD=1)。
- 递归解析器查自己的缓存,命中则返回。
- 未命中,解析器从根服务器开始迭代查询:问根 → 得到 .com TLD 地址。
- 问 .com TLD → 得到 example.com 权威服务器地址。
- 问 example.com 权威服务器 → 得到 www.example.com 的 A 记录(IP)。
- 解析器把结果缓存起来(按 TTL),并返回给客户端。
# 最常用的查询:默认就是递归查询
dig www.example.com
# 只返回简短答案
dig +short www.example.com
# 显式要求递归(默认行为)
dig +recurse www.example.com
# 显式禁用递归,观察是否被拒绝(很多服务器会返回 REFUSED)
dig +norecurse @8.8.8.8 www.example.com
看 dig 输出时,flags 行里的 qr rd ra 表示响应、期望递归、递归可用。如果响应里没有 ra,说明该服务器不支持递归。
五、用 dig +trace 看迭代全过程
想直观看迭代查询,最有效的命令是 dig +trace。它会从根开始,自己完成迭代查询并把每一级的回答打印出来:
# 从根服务器开始,逐级显示迭代过程
dig +trace www.example.com
# 只看每级 NS 和最终 A 记录
dig +trace +nodnssec www.example.com | grep -E 'IN\s+(NS|A)'
输出里你会看到依次查询了根(.)、.com、example.com,每一段都是"上一级告诉你下一级服务器地址"的迭代过程。注意 +trace 是 dig 自己模拟解析器做的迭代,绕过系统配置的递归解析器。
六、缓存、TTL 与"改了多久生效"
DNS 之所以快,全靠缓存。缓存分布在多个层级:
| 缓存位置 | 说明 | 典型 TTL |
|---|---|---|
| 浏览器 DNS 缓存 | 浏览器自身缓存 | 秒到分钟级 |
| 操作系统缓存 | systemd-resolved / nscd 等 | 由记录 TTL 决定 |
| 递归解析器缓存 | 最关键的一层,运营商/公共 DNS | 由记录 TTL 决定 |
| 权威服务器 | 数据源,非缓存 | 记录本身 |
TTL 是决定"域名变更多久生效"的关键参数。你把 A 记录从旧 IP 改成新 IP,递归解析器不会立刻知道,要等缓存过期(TTL)后重新查询才会拿到新值。所以:
- 迁移 IP 前,建议提前把 TTL 调小(如 300 秒或 60 秒),等旧缓存按小 TTL 过期后,再做切换,这样切换很快生效。
- 切换完成、稳定运行后再把 TTL 调回较大值(如 3600 秒),减少查询压力。
# 查询时看 TTL(第二列数字)
dig www.example.com +noall +answer
# 指定公共 DNS 查询,绕过本地缓存
dig @8.8.8.8 www.example.com +short
dig @223.5.5.5 www.example.com +short
七、根提示和 glue 记录
根提示(root hints):递归解析器怎么知道根服务器地址?靠一份内置的根提示文件,包含 13 组根服务器的 IP。BIND 里通常在 /var/named/named.ca 或 /etc/named.ca,systemd-resolved 也内置。
# 查看本机根提示文件(BIND)
cat /var/named/named.ca 2>/dev/null || cat /etc/named.ca 2>/dev/null
# 直接向根服务器查询(. 表示根)
dig . NS
glue 记录:这是个容易被忽略的细节。当 TLD 服务器要告诉解析器"example.com 的权威服务器是 ns1.example.com"时,ns1.example.com 自己就在 example.com 域内。解析器要拿 ns1.example.com 的 IP,就得分两步——可它连 example.com 的权威服务器地址都还不知道。为避免死循环,父域(.com)会额外提供 ns1.example.com 的 IP 地址,这条附带的 A/AAAA 记录就叫 glue 记录。没有 glue,解析会陷入"要查 A 得先知道 A"的循环。
八、递归与迭代对比
| 对比项 | 递归查询 | 迭代查询 |
|---|---|---|
| 发起方 | 客户端 → 递归解析器 | 递归解析器 → 各级权威 |
| 谁承担工作量 | 递归解析器 | 递归解析器自己逐级问 |
| 返回内容 | 最终答案(或错误) | "下一步问谁"的地址 |
| RD 标志 | RD=1 | RD=0 |
| 典型命令 | dig domain |
dig +trace domain |
| 是否可被拒绝 | 解析器可配置只服务特定客户端 | 权威服务器通常只做迭代 |
| 目的 | 让客户端省事 | 分散全球解析压力 |
理解这张表的现实意义:权威服务器一般不做递归(否则会被当"开放解析器"被滥用),所以你要用权威服务器查别的域名,它多半只给你"去问谁"。而递归解析器才是要配置好、要防滥用的那一层。
九、排查 DNS 问题的常用命令
# 指定服务器查询,区分是"解析器问题"还是"权威数据问题"
dig @8.8.8.8 www.example.com +short # 用公共 DNS
dig @ns1.example.com www.example.com +short # 直接问权威
# 检查各类型记录
dig example.com A
dig example.com MX
dig example.com NS
dig example.com TXT
# Ubuntu/Debian 上看本机用了哪个解析器
resolvectl status 2>/dev/null || cat /etc/resolv.conf
# RHEL/CentOS/Rocky
cat /etc/resolv.conf
# 清本机 DNS 缓存
# systemd-resolved 系统
sudo resolvectl flush-caches
# 有 nscd 的系统
sudo systemctl restart nscd
风险提示:修改
/etc/resolv.conf或 DNS 服务器配置前先备份;在 systemd-resolved 系统上直接编辑/etc/resolv.conf可能被覆盖,应改/etc/systemd/resolved.conf。改动后保留可用的备份解析器,避免全站解析中断。
常见问题
Q:dig +norecurse 有什么用?
A:用来验证某服务器是否只做迭代。如果它对非本域查询返回引用(去问谁)或不理你,说明它不提供递归;若返回答案,可能是开放解析器,存在被滥用的风险。
Q:为什么同一域名不同机器解析结果不一样?
A:缓存不同步或本地 TTL 未过期。用 dig @不同DNS 对比,或等 TTL 过期。也可能是解析线路做了智能 DNS(分运营商/地域返回不同 IP)。
Q:域名改了,为什么有的地方生效快有的慢?
A:各层缓存过期时间不同。改之前先把 TTL 调小,能显著加快全网生效速度;反之 TTL 设很大,旧记录会顽固留存。
Q:权威服务器能做递归查询吗?
A:一般不做,也不建议做。权威服务器只对自己负责的域做回答,做递归会带来开放解析器风险,容易被利用发起放大攻击。
Q:为什么解析有时快有时慢?
A:命中缓存就快(毫秒级),未命中要从根开始迭代,多几次往返,可能几十到上百毫秒。递归解析器离你越近、缓存命中率越高,体验越好。
总结
- 递归查询是"客户端让递归解析器查到底,只等最终答案",迭代查询是"递归解析器逐级问根、TLD、权威,每级只给下一步地址"。
- 完整链路:客户端缓存 → 递归解析器 → 根 → 顶级域 → 权威,逐层缓存,逐层 TTL 控制。
- TTL 决定变更生效速度:迁移前调小 TTL,稳定后再调大,是域名切换的标准操作。
- 根提示让解析器知道根服务器位置,glue 记录解决"权威服务器名在自身域内"的循环依赖问题。
- 排查用
dig @指定服务器区分解析器问题还是权威数据问题,dig +trace观察完整迭代路径,清缓存用resolvectl flush-caches或重启 nscd。
企业QQ咨询




