这是《计算机网络 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 DNS 把人类可读的域名转换为 IP 地址,是每一次外部访问的第一跳。它看似简单,实际是一个分层、缓存、可委托的全球分布式系统。DNS 解析失败、TTL 过长、地域调度错误或解析超时,都会直接影响可用性。
13.1 域名结构
www.example.com.
| | |
| | +-- TLD
| +--------- Second Level
+--------------- Subdomain
末尾的 . 表示 DNS 根,日常输入时通常省略。
解析层级:
Stub Resolver
-> Recursive Resolver
-> Root
-> TLD
-> Authoritative DNS
13.2 递归与迭代
客户端通常只向本地递归 DNS 发起请求:
浏览器 / 操作系统
-> Local Recursive DNS
-> 逐级查询
-> 返回最终 IP
递归 DNS 负责代替客户端完成迭代查询,并缓存结果。客户端看到的是一次递归查询。
13.3 常见记录
| 类型 | 说明 | 示例 |
|---|---|---|
| A | 域名到 IPv4 | 1.2.3.4 |
| AAAA | 域名到 IPv6 | 2001:db8::1 |
| CNAME | 别名指向另一域名 | cdn.example.net |
| NS | 委托子域解析 | ns1.example.com |
| MX | 邮件服务器 | 10 mail.example.com |
| TXT | 文本记录 | SPF、验证 |
| CAA | 允许签发证书的 CA | 0 issue "letsencrypt.org" |
| SRV | 服务地址和端口 | _sip._tcp |
| PTR | IP 反向解析 | 常用于邮件和日志 |
13.4 dig 与 nslookup
dig www.example.com
dig www.example.com A
dig www.example.com AAAA
dig www.example.com CNAME
dig @8.8.8.8 www.example.com
dig www.example.com +short
dig www.example.com +trace
dig -x 1.2.3.4
重点字段:
QUESTION SECTION:查询内容
ANSWER SECTION:结果和 TTL
AUTHORITY SECTION:授权 NS
Query time:查询耗时
SERVER:使用的 DNS 服务器
简单查看:
nslookup www.example.com
host www.example.com
resolvectl query www.example.com
13.5 缓存与 TTL
TTL 是记录可缓存时间:
TTL 300:缓存 300 秒
缓存层级:
浏览器
-> 操作系统
-> 家用路由器
-> 运营商 / 公共递归 DNS
-> 权威 DNS
切换 IP 前:
- 提前降低 TTL;
- 等待旧 TTL 过期;
- 切换记录;
- 多地验证解析;
- 保留旧服务可用;
- 观察流量迁移;
- 再恢复 TTL。
不要在 TTL 600 秒的情况下期待 DNS 切换立即生效。
13.6 负载均衡与地域调度
DNS 可以返回多个 A/AAAA 记录:
www.example.com A 1.1.1.1
www.example.com A 2.2.2.2
调度方式:
| 方式 | 特点 |
|---|---|
| 轮询 | 简单,无法感知健康 |
| 权重 | 可控比例,受缓存影响 |
| GeoDNS | 按解析者位置调度 |
| 健康检查 | 自动摘除故障地址 |
| Low TTL | 快速切换,递归压力大 |
局限:
- 客户端可能只用第一个地址;
- Local DNS 位置不等于用户位置;
- 缓存让权重不精确;
- 无法感知真实应用负载;
- 网络路径质量动态变化。
大型系统通常 DNS 只做入口和高层级调度,再由 LB 或服务发现做细粒度流量治理。
13.7 DNS 解析失败排查
dig @127.0.0.53 www.example.com
dig @8.8.8.8 www.example.com
dig @<authoritative-dns> www.example.com
cat /etc/resolv.conf
resolvectl status
定位顺序:
- 本机网络是否可用;
/etc/hosts是否覆盖;- 系统 resolver 是否异常;
- 公共 DNS 是否能解析;
- 权威 DNS 是否返回正确记录;
- 域名是否过期;
- NS 委托是否正确;
- TTL 缓存是否导致旧结果;
- AAAA 是否可用但 IPv6 路由异常。
13.8 应用中的 DNS
潜在问题:
- 启动时解析一次,之后 IP 变化不生效;
- 客户端未设置解析超时;
- 连接池没有感知地址变化;
- IPv4/IPv6 选择策略导致失败;
- DNS 服务不可用导致雪崩;
- 内部服务发现依赖单一 DNS。
实践:
- 设置解析和连接超时;
- 使用多个 DNS Server;
- 关键结果本地短缓存;
- 重试使用幂等策略;
- 定期刷新服务地址;
- 监控解析成功率和耗时;
- 内部服务发现准备降级方案。
Java 示例:
InetAddress[] addresses =
InetAddress.getAllByName("www.example.com");
for (InetAddress address : addresses) {
System.out.println(address.getHostAddress());
}
注意 JVM 的 DNS 缓存策略,容器和服务重启也会影响解析刷新。
13.9 DNS 安全
风险:
- DNS 劫持;
- 缓存投毒;
- DDoS;
- 子域接管;
- 泄露内部域名;
- 邮件伪造。
防护:
| 方案 | 作用 |
|---|---|
| DNSSEC | 签名验证,防篡改 |
| DNS over TLS / HTTPS | 加密本地到递归的查询 |
| CAA | 限制证书签发机构 |
| SPF / DKIM / DMARC | 邮件域保护 |
| 子域治理 | 清理悬挂 CNAME |
| 权限控制 | 防止记录被误改 |
DoH/DoT 加密查询链路,但不改变递归 DNS 可以看到目标域名这一事实。
本章小结
DNS 通过分层委托和递归查询完成域名到 IP 的转换,A、AAAA、CNAME、NS 和 TXT 等记录承载不同语义。TTL 决定缓存和切换速度,DNS 调度适合粗粒度入口选择,不能替代负载均衡和服务发现。排查 DNS 应从本机 resolver 到公共 DNS 再到权威 DNS 逐层验证,同时关注 IPv6、缓存和应用刷新策略。
思考题
- 递归查询和迭代查询分别由谁执行?
- 切换公网服务 IP 前,DNS TTL 应如何操作?
- 为什么 DNS 权重调度不精确?
dig +trace能帮助定位什么问题?- 设计一套内部服务的 DNS 超时、缓存和降级策略。