为域名设置 DNS 时——无论是指向自己的服务器、云服务还是 CDN——最常见的问题之一是:我应该使用 A 记录还是 CNAME?这两种 DNS 记录类型表面上似乎做类似的事情,但在它们的工作方式、灵活性和局限性上有根本的区别。本指南深入解释了每种记录类型,直接比较它们,并准确显示何时使用每一种。
什么是 A 记录?
A 记录(地址记录)是最基本的 DNS 记录类型之一。它将主机名直接映射到 IPv4 地址。当浏览器需要连接到 example.com 时,它向 DNS 解析器请求 IP 地址,A 记录直接提供该地址。
标准 A 记录语法:
example.com. 300 IN A 203.0.113.10 www.example.com. 300 IN A 203.0.113.10
在此示例中,example.com 和 www.example.com 都指向同一个 IP 地址。当服务器 IP 是静态的且不太可能改变时,此配置效果很好。但是,如果 IP 确实改变了,您必须单独更新每条引用该 IP 地址的 A 记录。
对于 IPv6 连接,等效的记录类型是 AAAA 记录,它存储 IPv6 地址(例如 2001:db8::1)而不是 IPv4。现代 DNS 配置应该包含 A 和 AAAA 记录,其中支持 IPv6。
什么是 CNAME 记录?
CNAME 记录(规范名称记录)的工作方式与 A 记录不同。它不是直接指向 IP 地址,而是将一个主机名指向另一个主机名,将解析 IP 的责任委托给目标主机名。
标准 CNAME 记录语法:
www.example.com. 300 IN CNAME example.com. blog.example.com. 300 IN CNAME example.com. shop.example.com. 300 IN CNAME myshop.shopify.com.
当解析器查询 www.example.com 并收到指向 example.com 的 CNAME 时,它会执行额外的查询来将 example.com 解析为 IP 地址。这个过程称为 CNAME 跟踪,并自动透明地进行。
CNAME 的主要优势是灵活性。如果 example.com 移至新的 IP 地址,您只需在一处更新 example.com 的 A 记录。指向它的每条 CNAME 都会自动继承新的 IP 地址,无需任何额外的更改。
并排比较
下表总结了 A 记录和 CNAME 记录之间的主要区别:
| 属性 | A 记录 | CNAME 记录 |
|---|---|---|
| 指向 | IPv4 地址(例如 203.0.113.10) | 另一个主机名(例如 example.com) |
| 可在根域使用 | 是的(建议用于 @) | 否(CNAME 拉平除外) |
| DNS 查询 | 1 步(直接解析为 IP) | 2+ 步(CNAME → 主机名 → IP) |
| IP 变化时 | 必须手动更新每条 A 记录 | 更新一次目标——所有 CNAME 自动继承更改 |
| 可与其他记录共存 | 是的(与 MX、TXT 等配合工作) | 否(必须是该名称的唯一记录) |
| 最适合 | 根域、静态服务器 IP | 子域、云服务、CDN |
CNAME 记录的关键限制
CNAME 记录有由 DNS 标准(RFC 1034)定义的重要约束,开发人员和管理员经常忽视这些约束。
1. CNAME 不能在根域(顶点)使用
顶点或根域是没有任何子域前缀的裸域——例如 example.com 而不是 www.example.com。根据 RFC 1034,具有 CNAME 记录的名称不能在同一名称下具有任何其他记录类型。但是,根域必须始终具有 SOA(权限起点)和 NS(名称服务器)记录——这与仅 CNAME 规则直接冲突。如果在顶点放置 CNAME,许多 DNS 解析器会拒绝或表现不稳定。
# 正确的方法 @ IN A 203.0.113.10 ; 根处的 A 记录——有效 www IN CNAME example.com. ; 子域处的 CNAME——有效 # 错误——不要这样做 @ IN CNAME something.cdn.com. ; 与 SOA/NS 记录冲突
2. CNAME 必须是该名称的唯一记录
具有 CNAME 记录的主机名不能与它一起具有任何其他记录类型(有限的 DNSSEC 例外除外)。这意味着如果子域具有 CNAME,则不能将 MX 记录添加到同一子域以接收电子邮件。您需要为邮件目的使用不同的子域名。
# 错误——mail.example.com 不能同时具有 CNAME 和 MX mail.example.com. IN CNAME mailserver.provider.com. mail.example.com. IN MX 10 mail.provider.com. ; 无效 # 正确——使用单独的子域名用于不同的目的 webmail.example.com. IN CNAME mailserver.provider.com. example.com. IN MX 10 mail.provider.com.
何时使用 A 记录
A 记录是这些情况下的正确选择:
- 根域(@ 或 example.com)——根据 DNS 标准在顶点处正确工作的唯一记录类型(除非您的提供商提供 ALIAS 或 CNAME 拉平)。
- 具有静态、可预测 IP 的服务器——VPS 或专用服务器,其中 IP 地址是已知的且很少改变。
- 需要其他记录类型的主机名——如果主机名需要用于电子邮件的 MX 记录或用于验证的 TXT 记录,请使用 A 记录(而不是 CNAME)以允许共存。
- 最小化 DNS 查询跳数——A 记录在单个查询步骤中解析,使其比 CNAME 链略有效率。
# 示例:自托管服务器的 A 记录 @ 3600 IN A 203.0.113.10 www 3600 IN A 203.0.113.10 mail 3600 IN A 203.0.113.20 ftp 3600 IN A 203.0.113.10
何时使用 CNAME 记录
CNAME 记录是这些情况下的正确选择:
- 将子域指向具有动态 IP 的云服务——AWS、GCP、Azure、Heroku、Vercel 和 Netlify 等服务通常提供主机名而不是固定 IP,因为它们的基础架构在许多服务器之间进行负载均衡。
- www 子域跟踪根——
www CNAME example.com自动将 www 与根保持同步,因此您只需管理一条 A 记录。 - 多个子域指向同一目标——如果 blog、shop 和 app 都需要指向同一 CDN 端点,每个都有一条 CNAME 意味着您只需要在需要时更改 CDN 主机名。
- 域验证挑战——许多服务(Google Search Console、SSL 提供商、电子邮件身份验证)要求您创建特定的 CNAME 记录来证明域所有权。
# 示例:云服务的 CNAME 记录 www 300 IN CNAME example.com. blog 300 IN CNAME mysite.netlify.app. shop 300 IN CNAME stores.example-ecom.com. _dmarc 300 IN CNAME dmarc-verify.provider.com.
CNAME 拉平和 ALIAS 记录——解决顶点问题
不在根域使用 CNAME 的限制在云服务或 CDN 仅提供主机名而不是固定 IP 时变成问题。几个 DNS 提供商提供变通方案:
CNAME 拉平(Cloudflare、NS1)
Cloudflare 允许您通过其仪表板为根域输入 CNAME。在内部,Cloudflare 在服务器端解析 CNAME 链并向客户端返回 A 记录,因此响应符合 DNS 标准。这使得可以将根域指向 Vercel、Netlify 或 GitHub Pages 等服务而不违反 RFC 规则。
ALIAS / ANAME 记录(Route53、DNSimple、Namecheap)
某些 DNS 提供商提供称为 ALIAS 或 ANAME 的专有记录类型,它们的行为类似于 CNAME 但可以安全地在顶点使用。提供商在向客户端提供响应之前将它们解析为 A 记录。
# Cloudflare——通过仪表板在根输入 CNAME;Cloudflare 处理拉平 @ CNAME myapp.vercel.app. # Route53——对顶点使用 ALIAS 记录类型 @ ALIAS myapp.elb.amazonaws.com.
专业提示:如果您使用 Cloudflare 作为您的名称服务器,您可以通过 Cloudflare 仪表板直接在根域输入 CNAME,而无需担心 RFC 违规。Cloudflare 在响应到达客户端之前在边缘处理 CNAME 拉平。这非常适合将根域指向 Vercel、Netlify 或 GitHub Pages。
真实世界 DNS 区域示例
以下示例显示了一个为典型商业网站正确使用 A 记录和 CNAME 记录的结构良好的 DNS 区域:
; example.com 的 DNS 区域 ; 根域——需要 A 记录 @ 3600 IN A 203.0.113.10 ; www 子域——CNAME 回到根以便于 IP 管理 www 300 IN CNAME example.com. ; 邮件服务器——A 记录(必须与 MX 共存) mail 3600 IN A 203.0.113.20 @ 3600 IN MX 10 mail.example.com. ; 云服务子域——CNAME 用于灵活性 blog 300 IN CNAME mysite.netlify.app. shop 300 IN CNAME exampleshop.myshopify.com. ; 静态资产的 CDN cdn 300 IN CNAME cdn-endpoint.cloudfront.net. ; SSL 验证挑战(ACME DNS-01 使用 TXT 记录,而非指向 letsencrypt.org 的 CNAME) _acme-challenge 60 IN TXT "ACME_DNS01_VALIDATION_TOKEN"
注意根域和邮件服务器使用 A 记录,因为邮件需要 MX 记录与之共存。云托管的子域使用 CNAME 记录,因为它们的 IP 可能会改变,并且没有其他记录类型与它共享相同的名称。_acme-challenge 条目使用 TXT 记录(而非 CNAME),其中包含 SSL 证书颁发期间 ACME DNS-01 挑战提供的验证令牌。
为每种记录类型正确设置 TTL
TTL(生存时间)控制 DNS 解析器在再次查询之前缓存记录的时间长度。不正确地设置 TTL 会影响解析速度和变化传播的速度:
- 具有稳定 IP 的 A 记录:3600–86400 秒(1–24 小时)。较高的 TTL 显著降低 DNS 查询负载。
- IP 可能变化的 A 记录:300–600 秒(5–10 分钟)用于更新期间的更快传播。
- 指向云服务的 CNAME 记录:300–900 秒。与目标服务的 TTL 保持一致。
- 在迁移或 IP 变化之前:至少提前 24–48 小时将 TTL 降低到 60–300 秒,以便在进行切换时缓存值快速过期。
; 按记录类型的 TTL 建议 @ 86400 IN A 203.0.113.10 ; 稳定 IP——1 天 TTL www 300 IN CNAME example.com. ; 低 TTL——灵活 blog 300 IN CNAME mysite.netlify.app. ; 匹配云 TTL
常见问题
CNAME 记录和 A 记录有什么技术区别?
A 记录将主机名直接映射到 IPv4 地址(例如 example.com → 203.0.113.10)。CNAME 将一个主机名映射到另一个主机名(例如 www.example.com → example.com)。当解析器遇到 CNAME 时,它必须执行额外的查询来将目标解析为 IP 地址,增加少量延迟但在基础 IP 变化时提供更大灵活性。
为什么不应该在根(顶点)域放置 CNAME?
根据 DNS 标准(RFC 1034),具有 CNAME 的名称不能在其下有任何其他记录类型。但根域始终需要 SOA 和 NS 记录,这与该规则冲突。解决方案是在根使用 A 记录,在 www 等子域使用 CNAME,或如果您的 DNS 提供商支持,使用 CNAME 拉平或 ALIAS 记录。
指向 Cloudflare 时应该使用 CNAME 还是 A 记录?
这取决于您配置的级别。对于指向 Cloudflare 的 www 或 blog 等子域,使用指向 Cloudflare 提供的主机名的 CNAME。对于根域,使用直接指向 Cloudflare IP 地址的 A 记录。Cloudflare 还通过其仪表板在根支持 CNAME 拉平,在响应到达客户端之前在内部将 CNAME 解析为 A 记录。
使用 CNAME 会让我的网站加载速度变慢吗?
与 A 记录相比,CNAME 增加一个额外的 DNS 查询步骤,理论上会增加少量延迟。但实际上,DNS 响应根据其 TTL 值进行缓存,所以在初始查询后,后续请求与 A 记录查询一样快。只要 TTL 值设置得当(300–3600 秒),对用户的实际影响可以忽略。