bc's club

This is Bc's club

计算机网络:自顶向下方法 - Day 4 | DNS 域名系统详解与 P2P 应用

📖 Day 4 / 15 · 《计算机网络:自顶向下方法》阅读笔记

每天 30 分钟,15 天读懂计算机网络。今天我们搞清楚两件事:DNS 是怎么把域名变成 IP 的,以及 P2P 怎么让人人成为服务器

一、DNS:互联网的电话簿#

1.1 没有 DNS 的世界#

先想象一个恐怖的场景:你打开浏览器,想刷个 B 站,但地址栏不能输入 bilibili.com,你得输入 120.240.95.33。想上百度?记一下 110.242.68.66。想看你的博客?那是 your-ecs-ip……

你可能会说:”没事,我把 IP 存收藏夹就行了。” 但问题在于,IP 地址是会变的。服务器迁移、负载均衡、运营商调整——今天能用的 IP,明天可能就失效了。

这就是为什么我们需要 DNS(Domain Name System,域名系统)

🎯 一句话理解 DNS

DNS 是一个分布式的、层次化的域名解析系统,它的工作就是把人类记得住的名字(bc970321.cn)翻译成机器认得出的地址(47.xxx.xxx.xx)。

生活类比:DNS 就是互联网的通讯录。你只需要记住联系人的名字(域名),通讯录帮你查到他的电话号码(IP 地址)。

1.2 DNS 的核心设计目标#

DNS 被设计时要满足几个关键目标:

  • 不依赖单一服务器:没有一个中心节点挂了全网就瘫的容错能力
  • 可扩展:能处理每天万亿级别的查询
  • 分布式管理:不同域名由不同机构管理,不存在”一家公司管全部”

这就决定了 DNS 必须是分布式的层次化的

1.3 DNS 的层次结构#

DNS 不是一棵光秃秃的树,而是一个有层级的倒金字塔:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
            ┌──────────────┐
根域名服务器 │ Root (.) │ 全球 13 组(A~M),掌管"一切的开端"
└──────┬───────┘

┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ .com │ │ .cn │ │ .org │ 顶级域名服务器(TLD)
└────┬─────┘ └────┬─────┘ └──────────┘
│ │
┌────┴────┐ ┌────┴────┐
│bilibili │ │bc970321 │ 权威域名服务器(Authoritative)
│ .com │ │ .cn │
└─────────┘ └─────────┘

三层结构解析:

层级 职责 生活类比
根域名服务器(Root) 指路:你想找 .cn 的?去问 .cn 那帮人 公司前台:你找技术部?上 3 楼
顶级域名服务器(TLD) 管理同一后缀下的所有域名 部门主管:你找张三?他工位在 B 区
权威域名服务器(Authoritative) 知道某个域名的最终 IP 张三本人:我的电话是 xxx

💡 关于根服务器的冷知识

全球只有 13 组根域名服务器(A 到 M),但这并不意味着只有 13 台机器。通过 Anycast(任播) 技术,全球部署了上千台根服务器镜像。你在中国查询根服务器,实际上很可能命中的是部署在境内的镜像节点。

1.4 域名解析的完整过程#

这是整篇文章最重要的部分,请集中注意力。

当你在浏览器输入 bc970321.cn 并按下回车,DNS 解析的完整流程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌─────────┐                    ┌──────────┐
│ 你的电脑 │ ──── 1.查 bc970321.cn ────→ │ 本地DNS │
│ (浏览器) │ │ 解析器 │
└─────────┘ │(运营商的) │
└────┬─────┘

2.缓存里没有,开始递归查询

┌────────────────┼────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 根服务器 │ │ │ │ │
│ "问.cn的"│ │ │ │ │
└─────┬────┘ └──────────┘ └──────────┘


┌──────────┐
│ .cn TLD │
│"问bc970321│
│ 权威服务器的"│
└─────┬────┘


┌──────────────┐
│bc970321.cn │
│权威服务器 │
│"IP是47.xxx" │
└──────────────┘

逐步解析:

  1. 浏览器缓存检查:浏览器先看自己记不记得这个域名的 IP。Chrome 默认缓存 60 秒。
  2. 操作系统缓存检查:操作系统也有 DNS 缓存(macOS 上可以用 dscacheutil -statistics 查看)。
  3. 本地 DNS 解析器(递归查询开始):前两步没找到,就去找配置的 DNS 服务器(通常是运营商的,或者你手动配的 8.8.8.8223.5.5.5 等)。
  4. 根域名服务器:本地解析器如果缓存里也没有,就从根开始问。根说:”我不知道 bc970321.cn 的 IP,但 .cn 的事归 .cn TLD 管,这是他的地址。”
  5. TLD 服务器:解析器接着去问 .cn TLD。TLD 说:”bc970321.cn 的具体信息归他的权威服务器管,这是地址。”
  6. 权威域名服务器:解析器最后去问 bc970321.cn 的权威服务器。这个服务器查了一下记录:”哦,bc970321.cn 的 A 记录是 47.xxx.xxx.xx。”
  7. 返回并缓存:解析器拿到 IP,返回给你的电脑,同时在每一层都缓存这个结果。下次再查就快了。

🧠 递归 vs 迭代

严格来说,客户端到本地解析器之间是递归查询(你帮我查到底),本地解析器到各级服务器之间是迭代查询(你告诉我下一步该问谁)。但很多教材简化了这个过程,理解核心思路就好。

1.5 DNS 缓存:让互联网跑得动的重要机制#

如果每次访问网站都要走一遍上面的完整流程,互联网早就卡死了。DNS 之所以能扛住万亿级查询,核心就在于缓存

每一层都会缓存查询结果,并设置一个 TTL(Time To Live,生存时间)

缓存位置 典型 TTL 说明
浏览器 60 秒 ~ 几分钟 最短,响应最快
操作系统 几分钟 ~ 几小时 系统级
本地 DNS 解析器 几小时 ~ 几天 影响所有使用该解析器的用户

💡 实战教训:TTL 的坑

当你修改域名的 DNS 记录(比如换 ECS IP),不是全网立刻生效的!因为各级缓存还没过期。如果你之前设置了 TTL = 3600 秒(1 小时),最坏情况下要等 1 小时旧缓存才过期,新的解析才生效。

这就是为什么你换服务器 IP 时,有人当天能访问新站,有人还在访问旧站——他们的本地 DNS 缓存还没更新。

1.6 DNS 记录类型#

DNS 不只是存”域名→IP”的映射,它维护着多种类型的记录:

记录类型 全称 作用 示例
A Address 域名 → IPv4 地址 bc970321.cn → 47.xxx.xxx.xx
AAAA IPv6 Address 域名 → IPv6 地址 未来趋势,现在用得少
CNAME Canonical Name 域名 → 另一个域名(别名) www.bc970321.cn → bc970321.cn
MX Mail Exchange 指定邮件服务器 bc970321.cn 的邮件发到 mail.bc970321.cn
NS Name Server 指定该域名由哪个 DNS 服务器管理 bc970321.cn NS → dns9.hichina.com
TXT Text 任意文本,常用于域名验证 “google-site-verification=xxx”

🔗 实战分析:你的 bc970321.cn 域名

你的域名在阿里云(万网)购买,DNS 解析也托管在阿里云。当你配置博客时,你在阿里云控制台做了这些操作:

  1. 添加 A 记录@ → 47.xxx.xxx.xx(ECS 的公网 IP),让 bc970321.cn 直接解析到你的服务器
  2. 可能还有 CNAME 记录www → bc970321.cn,让 www.bc970321.cn 也指向同一个地方
  3. NS 记录:自动配置为阿里云的 DNS 服务器(如 dns9.hichina.comdns10.hichina.com

当用户访问 bc970321.cn 时,DNS 系统最终会查询到阿里云上的权威服务器,拿到你的 A 记录,返回 ECS 的 IP。然后用户的浏览器直接连到这个 IP,通过 frps 隧道到达你的 Mac mini 上的 nginx。

1.7 用 dig 命令实战 DNS 查询#

理论说完了,来实际操作一下。打开终端,试试这些命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查询 bc970321.cn 的 A 记录
dig bc970321.cn A

# 查询详细解析过程(从根开始)
dig +trace bc970321.cn

# 查询 MX 记录(邮件)
dig bc970321.cn MX

# 查询 NS 记录(看域名服务器)
dig bc970321.cn NS

# 用指定 DNS 服务器查询(比如用 Google 的 8.8.8.8)
dig @8.8.8.8 bc970321.cn

dig +trace 特别推荐,你能清晰地看到从根服务器到 TLD 到权威服务器的整个迭代过程,就像跟着快递小哥跑了一趟完整的配送路线。

1.8 DNS 协议本身#

DNS 运行在 UDP 之上(端口 53),这看起来有点反直觉——DNS 这么重要的东西,怎么用不可靠的 UDP?

答案是:DNS 查询很小(通常一个 UDP 数据报就够了),而且追求速度。如果用 TCP,三次握手就要花时间。如果查询丢了,重发一次就行,代价远比每次建立 TCP 连接小。

💡 什么时候 DNS 会用 TCP?

当响应数据超过 512 字节时(比如大量记录),DNS 会切换到 TCP。此外,DNS 安全扩展(DNSSEC)的某些大响应也需要 TCP。但绝大多数情况,DNS 就是一个轻量级的 UDP 请求-响应。

1.9 DNS 安全问题#

DNS 设计于互联网早期,安全性并不完美:

  • DNS 劫持:攻击者篡改 DNS 响应,把你引导到假网站。你输入的是 bilibili.com,解析出来的却是攻击者的 IP。
  • DNS 污染(DNS Poisoning):在查询过程中注入伪造的 DNS 响应,让缓存记录错误的 IP。臭名昭著的”GFW DNS 污染”就是利用这个原理。
  • DNSSEC:DNS 安全扩展,用数字签名验证响应的真实性,是针对上述问题的解决方案,但目前普及度还不高。

🛡️ 你的实际体验

你在国内配置域名时选阿里云 DNS,除了稳定之外,也因为它支持 DNSSEC 和各种安全防护。如果你用国外 DNS(如 Cloudflare 的 1.1.1.1),配合 DoH/DoT(DNS over HTTPS/TLS)可以加密 DNS 查询,防止被监听和篡改。


二、P2P 应用:人人都是服务器#

2.1 从 C/S 到 P2P#

前面几天的内容里,我们讨论的网络应用都是 C/S(客户端/服务器)架构

1
2
3
4
┌────────┐  请求   ┌────────┐
│ Client │ ──────→ │ Server │
│ │ ←────── │ │
└────────┘ 响应 └────────┘

C/S 架构的问题很明显:服务器是瓶颈。用户越多,服务器压力越大。你搞个热门活动,服务器就崩了——双十一剁手的你一定深有体会。

P2P(Peer-to-Peer,对等网络) 架构则是另一个思路:

1
2
3
4
5
6
7
8
┌────────┐
│ Peer A │ ←──→ ┌────────┐
└────────┘ │ Peer B │
↕ └────────┘
┌────────┐ ↕
│ Peer C │ ←──→ ┌────────┐
└────────┘ │ Peer D │
└────────┘

在 P2P 架构中:

  • 没有中心服务器(或者服务器只起辅助作用)
  • 每个节点(Peer)既是客户端也是服务端
  • 节点之间直接通信,数据不需要经过中间服务器

🎯 生活类比

C/S 架构就像老师讲课:所有学生(客户端)都听老师(服务器)一个人的,老师嗓子哑了全班就停课。

P2P 架构就像学习小组:每个同学既学又教,张三教李四数学,李四教张三英语。少了谁都能继续运转,人越多知识越丰富。

2.2 P2P 的核心优势:自扩展性#

P2P 最迷人的特性叫自扩展性(Self-scalability)

在 C/S 架构中,如果 N 个用户同时下载一个文件:

  • 服务器要承受 N 倍的上传带宽压力
  • 总下载速度受限于服务器带宽

在 P2P 架构中:

  • 每个下载者同时也是上传者
  • 用户越多,可用的上传源就越多
  • 系统的总容量随着用户数自动增长

这就是为什么 BitTorrent 下载几百 GB 的游戏镜像依然很快——种子越多,下载源越多。

📊 量化对比

假设一个文件大小 F,服务器上传速度 u_s,每个用户的下载速度 d_i:

  • C/S 架构:N 个用户全部下完的时间 ≥ max(NF/u_s, F/d_min),服务器是瓶颈
  • P2P 架构:N 个用户全部下完的时间大致 ≈ max(F/u_s, F/d_min, NF/(u_s + Σu_i)),随着用户增多,总上传能力 Σu_i 增长,瓶颈转移

2.3 P2P 文件分发:BitTorrent#

BitTorrent 是最经典的 P2P 文件分发协议,至今仍是全球互联网流量的重要组成部分。

核心概念:

概念 说明
种子文件(.torrent) 记录文件的元数据:分块信息、Tracker 地址等
Tracker 一个中央服务器,帮助 Peers 互相发现(注意,它不传输文件本身)
分块(Chunk) 大文件被切成 256KB~1MB 的小块,Peers 互相交换
种子(Seeder) 拥有完整文件并继续上传的节点
下载者(Leecher) 还在下载中的节点,同时也在上传已有的块

BitTorrent 的工作流程:

  1. 用户打开 .torrent 文件,客户端连接到 Tracker
  2. Tracker 返回一个当前在线的 Peers 列表
  3. 客户端与这些 Peers 建立 TCP 连接
  4. 最稀缺优先(Rarest First):优先请求整个群体中拥有数最少的块,确保每个块都有足够的副本
  5. 针锋相对(Tit-for-Tat):你给我上传数据,我也给你上传;你不给我,我也不给你。这是 BitTorrent 的激励机制——白嫖是不行的

🧠 针锋相对的智慧

BitTorrent 的”针锋相对”策略其实来自博弈论中的经典策略。它鼓励合作,惩罚搭便车(Free-riding)。如果你只下载不上传,很快就没人和你交换数据了,你的下载速度会变得极其缓慢。

2.4 P2P 的挑战:如何找到对方?#

C/S 架构很简单——你知道服务器的 IP,直接连过去就行。但 P2P 里没有中心服务器,两个 Peer 怎么找到彼此?

这是 P2P 最核心的技术难题,有几种解决方案:

方案一:集中式目录#

用一个中央服务器维护”谁有什么文件”的目录。Napster(最早的 P2P 音乐分享)就是这种模式。

  • 优点:简单、查询快
  • 缺点:单点故障——服务器关了,整个网络就废了。Napster 就是被法院判令关闭服务器而覆灭的

方案二:泛洪查询(Gnutella 风格)#

不需要中心服务器。想找文件?问你的邻居节点,邻居再问他们的邻居,层层扩散。

  • 优点:完全去中心化,抗审查
  • 缺点:查询效率极低,网络流量大。就像你在人群里大喊”谁有这部电影”,几百万人都在喊,整个广场一片嘈杂

方案三:DHT(分布式哈希表)#

这是目前最优雅的方案。核心思想:给每个节点和每个文件分配一个 ID,然后按照规则让节点”各司其职”。

最著名的是 Chord 算法和 Kademlia 算法(BitTorrent 中的 DHT 就是 Kademlia 的变种)。

🎯 DHT 生活类比

想象一个图书馆,没有总索引,但每本书的编号和书架编号是数学相关的。你要找编号 #42 的书,不需要问管理员,直接根据编号规则走到对应的书架。每个书架不仅放自己的书,还知道”如果我这里没有,应该去哪个书架找”。

Kademlia DHT 中,每个节点有一个 160 位的 ID,文件也用同样方式生成 ID(通过哈希)。查找文件时:

  1. 计算文件的 ID
  2. 询问自己知道的、距离目标 ID 最近的节点
  3. 那个节点再告诉你更近的节点
  4. 逐步逼近,最终找到拥有文件的节点

这里的”距离”不是物理距离,而是异或距离(XOR):两个 ID 的异或值越小,距离越近。

2.5 P2P 的现实应用#

P2P 不只是”下载工具”那么简单,它在很多场景中默默工作:

应用领域 典型代表 说明
文件分享 BitTorrent 全球最大的 P2P 文件分发协议
区块链/加密货币 Bitcoin, Ethereum 每个全节点都是 P2P 网络的一部分
实时通信 WebRTC 浏览器之间的直接音视频通话
内容分发 IPFS “星际文件系统”,用 P2P 重构 HTTP
VPN 代理 各种 mesh VPN 节点间直接加密通信

💡 WebRTC 和你的关系

你用浏览器视频通话(比如 Google Meet)时,如果网络条件允许,浏览器之间会尝试建立 P2P 直连,音视频数据直接在两个人之间传输,不经过中间服务器。这就是 WebRTC 的 P2P 能力。

2.6 CDN:不是 P2P,但解决了类似的问题#

说到大规模内容分发,不能不提 CDN(Content Distribution Network,内容分发网络)

CDN 的思路和 P2P 相反——它用的是”大量服务器”,但核心目的类似:让用户就近获取内容,减轻源站压力。

1
2
3
4
5
6
7
8
9
10
11
12
13
               ┌──────────────┐
│ 源站服务器 │ ← 原始内容
└──────┬───────┘
│ 同步内容
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ CDN 节点 │ │ CDN 节点 │ │ CDN 节点 │
│ (北京) │ │ (上海) │ │ (广州) │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
北京用户 上海用户 广州用户
就近访问 就近访问 就近访问

CDN 使用 DNS 重定向 来实现就近访问:

  1. 用户查询 cdn.example.com 的 DNS
  2. CDN 的权威 DNS 服务器检查请求来源(根据 Local DNS 的 IP 判断用户大概位置)
  3. 返回距离用户最近的 CDN 节点 IP

🔗 CDN 和你的博客

你的博客目前没有用 CDN,用户访问 bc970321.cn 时,DNS 直接返回 ECS 的 IP,所有请求都打到那一台机器上。如果未来流量增大,可以考虑:

  • Cloudflare 免费 CDN:修改 NS 记录指向 Cloudflare,DNS 解析自动返回最近的 CDN 节点
  • 或者用 阿里云 CDN:在阿里云控制台配置加速域名,回源到你的 ECS

这两种方案的核心都是修改 DNS 记录——怎么样,是不是和前面学的 DNS 知识连上了?


三、把今天的东西串起来#

让我们用一张完整的图,描述从 DNS 到内容分发的全流程,以你的博客为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
用户输入 bc970321.cn


┌────────────────────────────────────────────┐
│ DNS 解析过程 │
│ │
│ 浏览器缓存 → OS 缓存 → 本地解析器(递归) │
│ ↓ │
│ 根服务器 → .cn TLD → 阿里云权威服务器 │
│ ↓ │
│ 返回 A 记录: 47.xxx.xxx.xx (ECS 公网 IP) │
│ │
│ 协议: UDP, 端口 53 │
└────────────────────┬───────────────────────┘


┌────────────────────────────────────────────┐
│ HTTP 连接 │
│ │
│ 浏览器 → 47.xxx.xxx.xx:80/443 │
│ ECS 上的 frps → 隧道 → Mac mini nginx │
│ nginx 返回博客页面 │
└────────────────────────────────────────────┘

如果你想给博客加上 CDN:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
用户输入 bc970321.cn


┌────────────────────────────────────────────┐
│ DNS 解析(CDN 模式) │
│ │
│ NS 记录指向 Cloudflare/阿里云CDN │
│ CDN 的智能 DNS 返回最近节点 IP │
│ 比如: 北京用户 → 120.xxx.xxx.xx (CDN 节点) │
└────────────────────┬───────────────────────┘


┌────────────────────────────────────────────┐
│ CDN 节点 │
│ │
│ 有缓存? → 直接返回 │
│ 无缓存? → 回源到 ECS → frps → Mac mini │
│ 缓存后返回给用户 + 后续命中 │
└────────────────────────────────────────────┘

DNS 不只是”查地址”,它是整个互联网流量调度的基础设施。CDN、负载均衡、灰度发布,底层都在玩 DNS 的花样。


🎯 关键知识点回顾#

  1. DNS 是互联网的分布式电话簿,把域名翻译成 IP 地址
  2. DNS 三层结构:根服务器 → TLD 服务器 → 权威服务器,层层递进
  3. 解析过程:浏览器缓存 → OS 缓存 → 本地解析器 → 根 → TLD → 权威,逐级返回并缓存
  4. DNS 用 UDP,端口 53,因为查询小且追求速度
  5. TTL 决定缓存生效时间,修改 DNS 记录后需要等 TTL 过期才能全网生效
  6. 常见 DNS 记录:A(IPv4)、AAAA(IPv6)、CNAME(别名)、MX(邮件)、NS(域名服务器)、TXT(文本验证)
  7. P2P 架构中每个节点既是客户端也是服务端,具有自扩展性
  8. BitTorrent 使用最稀缺优先和针锋相对策略,激励用户上传
  9. DHT 解决了 P2P 网络中”怎么找到对方”的问题,Kademlia 是最广泛使用的算法
  10. CDN 通过 DNS 重定向实现就近访问,是大规模内容分发的工业标准

📌 Day 5 预告:Socket 编程基础 & 邮件协议(SMTP/IMAP)

明天我们从理论走向代码——Socket 编程,亲手实现一个客户端和服务端。然后看看每天收发邮件背后的 SMTPIMAP 协议是怎么工作的。

邮件协议是应用层最经典的协议之一,理解了它,你就理解了消息系统设计的核心思想。明天见!


本文是基于《计算机网络:自顶向下方法》(第8版)的读书笔记,结合实际操作经验编写。