为域名设置 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 记录是这些情况下的正确选择:

# 示例:自托管服务器的 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 记录是这些情况下的正确选择:

# 示例:云服务的 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 会影响解析速度和变化传播的速度:

; 按记录类型的 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 秒),对用户的实际影响可以忽略。

使用 AsiaGB 注册域名

注册 .com、.net 和 .co.th 域名,包括完整 DNS 管理和免费 WHOIS 隐私。

注册域名