- Published on
域名解析的完整链条:从购买域名到访问网站
- Authors

- Name
- Terry
引言
当你在浏览器输入 www.example.com 并按下回车,网页就神奇地显示出来了。这个看似简单的过程,背后其实经历了一系列复杂的步骤。今天我们就来拆解这个过程,看看一个域名是如何找到它对应的 IP 地址的。
第一步:购买域名
一切从购买域名开始。
1.1 选择域名注册商
域名注册商(Domain Registrar)是经过 ICANN(互联网名称与数字地址分配机构)认证的公司,常见的有:
- GoDaddy
- Namecheap
- Cloudflare
- 阿里云(万网)
- 腾讯云
1.2 注册流程
假设你想注册 mysite.com:
- 在注册商网站搜索域名是否可用
- 如果可用,支付年费(通常 $10-15/年)
- 填写域名所有者信息(WHOIS 信息)
- 完成注册
此时,你拥有了这个域名的使用权(通常是一年),但它还不能指向任何网站。
第二步:理解 DNS 系统
在配置域名之前,我们需要理解 DNS(Domain Name System)是什么。
2.1 DNS 的作用
DNS 就像互联网的电话簿,它的作用是:
域名(人类可读) → IP 地址(机器可读)
www.example.com → 93.184.216.34
2.2 DNS 的层级结构
DNS 是一个分层的系统:
. (根域名)
├── .com (顶级域名 TLD)
│ ├── example.com (二级域名)
│ │ ├── www.example.com (三级域名/子域名)
│ │ └── blog.example.com (三级域名/子域名)
│ └── google.com
├── .org
└── .cn
第三步:配置 DNS 记录
购买域名后,你需要在域名注册商或 DNS 服务商那里配置 DNS 记录。
3.1 选择 DNS 服务商
你有两个选择:
- 使用注册商的 DNS 服务:大多数注册商提供免费的 DNS 服务
- 使用第三方 DNS 服务:如 Cloudflare、AWS Route 53、DNSPod
第三方 DNS 服务通常更快、更稳定,还提供额外功能(如 CDN、DDoS 防护)。
3.2 常见的 DNS 记录类型
A 记录(Address Record)
最基本的记录类型,将域名直接指向 IPv4 地址:
类型: A
名称: @(或留空,表示根域名)
值: 76.76.21.21
TTL: 3600
A 记录必须指向 IP 地址,这里的 76.76.21.21 是什么?
- 这是 Vercel 的负载均衡器 IP 地址
- 当用户访问你的域名时,会直接连接到这个 IP
- Vercel 在这个 IP 后面部署了多台服务器,通过负载均衡分发请求
- 这个 IP 是 Vercel 专门为自定义域名提供的入口点
为什么不直接用你应用的真实 IP?
- 负载均衡:Vercel 有多台服务器,需要智能分发流量
- 高可用性:如果某台服务器故障,可以自动切换
- 全球 CDN:这个 IP 可能指向离用户最近的边缘节点
- 弹性扩容:后端服务器可以动态增减,不影响前端 IP
这意味着 mysite.com 指向 76.76.21.21。
AAAA 记录
类似 A 记录,但指向 IPv6 地址:
类型: AAAA
名称: @
值: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
TTL: 3600
CNAME 记录(Canonical Name)
将域名指向另一个域名(别名):
类型: CNAME
名称: www
值: cname.vercel-dns.com
TTL: 3600
CNAME 解析流程详解:
当用户访问 www.mysite.com 时,DNS 解析过程是这样的:
- 第一次查询:
www.mysite.com→ DNS 返回cname.vercel-dns.com - 第二次查询:
cname.vercel-dns.com→ DNS 返回最终 IP 地址(如76.76.21.21) - 建立连接:浏览器使用这个 IP 地址连接服务器
为什么 Vercel 使用 cname.vercel-dns.com?
- 动态 IP 管理:Vercel 可以随时更改后端 IP,只需更新
cname.vercel-dns.com的 A 记录 - 智能路由:根据用户地理位置返回不同的 IP(GeoDNS)
- 负载均衡:可以返回多个 IP 实现负载分担
- 故障转移:某个 IP 故障时,可以快速切换到备用 IP
CNAME vs A 记录的选择:
- A 记录:直接解析,速度快 1-2ms,但 IP 变化需要手动更新
- CNAME:间接解析,多一次 DNS 查询,但 IP 变化时自动跟随
重要限制:
- CNAME 不能用于根域名(
@) - 一个域名只能有一个 CNAME 记录
- CNAME 记录不能与其他记录类型共存
MX 记录(Mail Exchange)
指定邮件服务器:
类型: MX
名称: @
值: mail.mysite.com
优先级: 10
TTL: 3600
TXT 记录
存储文本信息,常用于域名验证:
类型: TXT
名称: @
值: "v=spf1 include:_spf.google.com ~all"
TTL: 3600
3.3 TTL(Time To Live)
TTL 是缓存时间,单位是秒:
3600= 1 小时86400= 24 小时
TTL 越短,DNS 更新越快,但查询次数越多。
第四步:域名解析到访问的完整流程
让我们用你提到的具体例子,详细分析从域名解析到最终访问网站的完整过程。
4.0 配置示例分析
假设你的域名配置如下:
类型: A
名称: @
值: 76.76.21.21
TTL: 3600
类型: CNAME
名称: www
值: cname.vercel-dns.com
TTL: 3600
4.1 访问根域名的流程(example.com)
当用户在浏览器输入 example.com 时:
1. 浏览器发起 DNS 查询:example.com
↓
2. DNS 服务器返回:A 记录 → 76.76.21.21
↓
3. 浏览器直接连接到 76.76.21.21:443 (HTTPS)
↓
4. Vercel 负载均衡器接收请求
↓
5. 根据 Host 头(example.com)路由到对应的应用
↓
6. 返回网页内容
关键点:
- 只需要 1 次 DNS 查询
76.76.21.21是 Vercel 的 入口 IP,不是你应用的真实服务器 IP- Vercel 在这个 IP 后面有多台服务器,通过内部负载均衡分发请求
4.2 访问 www 子域名的流程(www.example.com)
当用户访问 www.example.com 时:
1. 浏览器发起 DNS 查询:www.example.com
↓
2. DNS 服务器返回:CNAME → cname.vercel-dns.com
↓
3. 浏览器再次查询:cname.vercel-dns.com
↓
4. DNS 服务器返回:A 记录 → 76.76.19.88 (可能与根域名不同)
↓
5. 浏览器连接到 76.76.19.88:443
↓
6. Vercel 负载均衡器接收请求
↓
7. 根据 Host 头(www.example.com)路由到对应的应用
↓
8. 返回网页内容
关键点:
- 需要 2 次 DNS 查询(CNAME + A 记录)
cname.vercel-dns.com可能解析到不同的 IP,实现更灵活的负载均衡- Vercel 可以根据地理位置、服务器负载等因素动态返回最优 IP
4.3 为什么 Vercel 使用这种架构?
A 记录指向固定 IP(76.76.21.21):
- 为根域名提供稳定的入口点
- 满足 DNS 规范(根域名不能用 CNAME)
- 提供基础的负载均衡能力
CNAME 指向动态域名(cname.vercel-dns.com):
- 可以根据实时情况返回不同 IP
- 支持 GeoDNS(地理位置路由)
- 便于故障转移和扩容
4.4 关键问题:服务器如何知道访问的是哪个域名?
问题:如果多个域名(如 example.com、myblog.com、test.com)都指向同一个 IP 76.76.21.21,服务器怎么知道用户访问的是哪个域名?
答案:通过 HTTP Host 头!
4.5 HTTP 请求的完整过程
当用户在浏览器输入 example.com 时:
步骤 1:DNS 解析
用户输入: example.com
DNS 查询: example.com → 76.76.21.21
步骤 2:建立 TCP 连接
浏览器连接到: 76.76.21.21:443 (HTTPS)
步骤 3:发送 HTTP 请求(关键!)
GET / HTTP/1.1
Host: example.com ← 这里!浏览器告诉服务器访问的域名
User-Agent: Mozilla/5.0...
Accept: text/html...
步骤 4:服务器处理请求
Vercel 负载均衡器接收请求
↓
读取 Host 头: example.com
↓
查找域名映射表:
- example.com → project-abc123
- myblog.com → project-def456
- test.com → project-ghi789
↓
找到对应项目: project-abc123
↓
转发到对应的应用服务器
4.6 Host 头的工作原理
同一个 IP,不同的域名:
# 用户 A 访问 example.com
GET / HTTP/1.1
Host: example.com
→ 路由到项目 A
# 用户 B 访问 myblog.com
GET / HTTP/1.1
Host: myblog.com
→ 路由到项目 B
# 用户 C 访问 test.com
GET / HTTP/1.1
Host: test.com
→ 路由到项目 C
这就是虚拟主机(Virtual Host)的原理:
- 一个 IP 地址可以托管无数个网站
- 服务器通过 Host 头区分不同的域名
- 这是现代 Web 服务器的标准做法
4.7 Vercel 的域名路由系统
Vercel 内部维护一个域名映射表:
// Vercel 内部的域名映射(简化版)
const domainMapping = {
'example.com': {
projectId: 'prj_abc123',
deploymentId: 'dpl_xyz789',
serverPool: 'us-east-1'
},
'www.example.com': {
projectId: 'prj_abc123', // 同一个项目
deploymentId: 'dpl_xyz789',
serverPool: 'us-east-1'
},
'myblog.com': {
projectId: 'prj_def456',
deploymentId: 'dpl_uvw012',
serverPool: 'eu-west-1'
}
}
// 请求处理逻辑
function handleRequest(request) {
const host = request.headers.host; // 获取 Host 头
const config = domainMapping[host];
if (!config) {
return '404 - Domain not found';
}
// 转发到对应的应用服务器
return forwardToApp(config.projectId, request);
}
4.8 实际的网络包分析
让我们看看真实的 HTTP 请求:
访问 example.com 的请求:
→ TCP 连接到 76.76.21.21:443
→ TLS 握手(SNI: example.com)
→ HTTP 请求:
GET / HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0...
← HTTP 响应:
HTTP/1.1 200 OK
Server: Vercel
Content-Type: text/html
<!DOCTYPE html>
<html>...</html>
访问 myblog.com 的请求:
→ TCP 连接到 76.76.21.21:443 (同一个 IP!)
→ TLS 握手(SNI: myblog.com)
→ HTTP 请求:
GET / HTTP/1.1
Host: myblog.com (不同的 Host 头!)
User-Agent: Mozilla/5.0...
← HTTP 响应:
HTTP/1.1 200 OK
Server: Vercel
Content-Type: text/html
<!DOCTYPE html>
<html>...</html> (完全不同的网站内容!)
4.9 为什么这样设计?
优势:
- IP 地址节约:一个 IP 可以服务无数个域名
- 成本降低:不需要为每个域名分配独立 IP
- 负载均衡:可以在同一个负载均衡器后面部署多个应用
- 扩展性好:添加新域名不需要新的 IP 资源
技术要求:
- HTTP/1.1 协议必须包含 Host 头(RFC 2616)
- HTTPS 需要 SNI(Server Name Indication)支持多证书
- 服务器需要维护域名到应用的映射关系
这就是为什么:
- 你看到的 IP(76.76.21.21)不是你应用的真实 IP
- 多个域名可以指向同一个 IP,通过 Host 头区分
- Vercel 可以在不影响 DNS 的情况下,内部调整服务器部署
- 现代 CDN 和云服务商都使用这种架构
4.10 如何验证 Host 头的工作?
你可以用命令行工具验证这个过程:
方法 1:使用 curl 测试不同域名
# 测试 example.com(假设都指向 76.76.21.21)
curl -H "Host: example.com" http://76.76.21.21
# 测试 myblog.com(同一个 IP,不同的 Host 头)
curl -H "Host: myblog.com" http://76.76.21.21
# 测试不存在的域名
curl -H "Host: nonexistent.com" http://76.76.21.21
# 可能返回 404 或默认页面
方法 2:查看实际的 HTTP 请求
# 使用 curl 显示完整的请求和响应
curl -v https://example.com
# 你会看到类似这样的输出:
# > GET / HTTP/1.1
# > Host: example.com ← 这里是关键
# > User-Agent: curl/7.68.0
# > Accept: */*
# < HTTP/1.1 200 OK
# < server: Vercel ← Vercel 的响应
方法 3:使用浏览器开发者工具
- 打开浏览器开发者工具(F12)
- 访问你的网站
- 查看 Network 标签
- 点击第一个请求,查看 Request Headers
- 找到
Host: your-domain.com
第五步:DNS 解析过程
现在我们来看 DNS 解析的技术细节。
5.1 完整的解析链条
假设用户访问 www.mysite.com:
1. 浏览器缓存
↓ (未找到)
2. 操作系统缓存
↓ (未找到)
3. 本地 DNS 服务器(通常是 ISP 提供)
↓ (未找到)
4. 根 DNS 服务器
↓ (返回 .com 的 DNS 服务器地址)
5. 顶级域名服务器(.com)
↓ (返回 mysite.com 的 DNS 服务器地址)
6. 权威 DNS 服务器(mysite.com)
↓ (返回最终的 IP 地址)
7. 返回给用户
5.2 递归查询 vs 迭代查询
递归查询:客户端只发一次请求,DNS 服务器负责完成所有查询工作。
用户 → 本地DNS → 根DNS → TLD DNS → 权威DNS
← ← ← ← ← ← ← ← ← ← ← ← ←
迭代查询:DNS 服务器返回下一个应该查询的服务器地址,客户端自己继续查询。
用户 → 根DNS → 返回 TLD DNS 地址
用户 → TLD DNS → 返回权威 DNS 地址
用户 → 权威DNS → 返回 IP 地址
实际上,通常是递归+迭代的混合模式。
5.3 DNS 缓存
为了提高效率,DNS 查询结果会在多个层级缓存:
- 浏览器缓存:Chrome 缓存 60 秒
- 操作系统缓存:根据 TTL 设置
- 路由器缓存:家用路由器也会缓存
- ISP DNS 缓存:运营商的 DNS 服务器缓存
这就是为什么修改 DNS 记录后,不会立即生效的原因。
第六步:实战案例 - 部署 Next.js 应用到 Vercel
现在我们用一个真实案例,看看如何将域名指向 Next.js 应用。
6.1 场景描述
- 你有一个域名:
myblog.com - 你的 Next.js 应用部署在 Vercel 上
- Vercel 给你分配了一个默认域名:
myblog.vercel.app
6.2 配置步骤
步骤 1:在 Vercel 添加自定义域名
- 进入 Vercel 项目设置
- 点击 "Domains"
- 输入
myblog.com和www.myblog.com - Vercel 会提示你需要配置的 DNS 记录
步骤 2:配置 DNS 记录
在你的 DNS 服务商(如 Cloudflare)添加以下记录:
方案 A:使用 A 记录(推荐用于根域名)
类型: A
名称: @
值: 76.76.21.21
TTL: 3600
类型: CNAME
名称: www
值: cname.vercel-dns.com
TTL: 3600
方案 B:使用 CNAME(仅适用于子域名)
类型: CNAME
名称: www
值: myblog.vercel.app
TTL: 3600
注意:根域名(@)不能使用 CNAME,必须使用 A 记录。
步骤 3:等待 DNS 传播
DNS 记录更新后,需要等待传播:
- 最快:几分钟
- 通常:1-2 小时
- 最慢:24-48 小时(极少见)
6.3 验证 DNS 配置
使用命令行工具验证:
# 查询 A 记录
dig myblog.com
# 查询 CNAME 记录
dig www.myblog.com
# 使用特定 DNS 服务器查询
dig @8.8.8.8 myblog.com
或者使用在线工具:
第七步:HTTPS 证书
配置好 DNS 后,还需要 HTTPS 证书。
7.1 Let's Encrypt
Vercel 会自动为你的域名申请免费的 Let's Encrypt 证书:
- DNS 记录生效后
- Vercel 自动向 Let's Encrypt 申请证书
- 证书自动续期
7.2 证书验证方式
Let's Encrypt 使用 DNS 验证或 HTTP 验证:
- DNS 验证:在 DNS 中添加 TXT 记录
- HTTP 验证:在网站根目录放置验证文件
Vercel 通常使用 HTTP 验证,所以你不需要手动操作。
第八步:高级配置
8.1 使用 Cloudflare 作为 CDN
如果你使用 Cloudflare:
- 将域名的 Nameserver 改为 Cloudflare 的
- 在 Cloudflare 添加 DNS 记录
- 开启 "Proxied" 模式(橙色云朵)
此时的解析链条变成:
用户 → Cloudflare CDN → Vercel 服务器
8.2 多区域部署
对于全球用户,可以使用 GeoDNS:
类型: A
名称: @
值: 192.0.2.1 (美国服务器)
地理位置: 北美
类型: A
名称: @
值: 198.51.100.1 (欧洲服务器)
地理位置: 欧洲
用户会自动连接到最近的服务器。
8.3 负载均衡
使用多个 A 记录实现简单的负载均衡:
类型: A
名称: @
值: 192.0.2.1
TTL: 60
类型: A
名称: @
值: 192.0.2.2
TTL: 60
DNS 会轮询返回不同的 IP 地址。
常见问题
Q1: 为什么 DNS 修改后没有立即生效?
因为 DNS 缓存。解决方法:
- 等待 TTL 时间过期
- 清除本地 DNS 缓存:
ipconfig /flushdns(Windows)或sudo dscacheutil -flushcache(Mac) - 使用隐私模式浏览器测试
Q2: A 记录和 CNAME 有什么区别?
- A 记录:直接指向 IP 地址,速度快,但 IP 变化时需要手动更新
- CNAME:指向另一个域名,IP 变化时自动跟随,但多一次 DNS 查询
Q3: 为什么根域名不能使用 CNAME?
因为 DNS 规范(RFC 1034)规定,如果一个域名有 CNAME 记录,就不能有其他记录(如 MX、TXT)。而根域名通常需要 MX 记录(邮件)和其他记录。
Q4: 如何加速 DNS 解析?
- 使用更快的 DNS 服务商(如 Cloudflare 1.1.1.1、Google 8.8.8.8)
- 减少 DNS 查询次数(减少外部资源)
- 使用 DNS 预解析:
<link rel="dns-prefetch" href="//example.com"> - 适当增加 TTL 值
总结
域名解析的完整链条:
- 购买域名 → 从注册商获得域名使用权
- 配置 DNS → 添加 A/CNAME 等记录
- DNS 查询 → 浏览器通过多级 DNS 服务器查询 IP
- 建立连接 → 使用 IP 地址连接到服务器
- HTTPS 握手 → 验证证书,建立加密连接
- 传输数据 → 下载网页内容
整个过程看似复杂,但实际上只需要几百毫秒。理解这个过程,可以帮助你:
- 更好地配置域名和 DNS
- 排查网站访问问题
- 优化网站性能
- 理解互联网的基础设施
希望这篇文章能帮助你理解域名解析的全过程。如果你有任何问题,欢迎在评论区讨论。