面试官:CNAME和A记录有什么区别?

配置域名解析的时候,经常看到A记录、CNAME这些选项:

  • A记录和CNAME到底有什么区别?
  • 为什么GitHub Pages要求添加CNAME记录?
  • 什么时候该用A记录,什么时候该用CNAME?

先说结论

对比项 A记录 CNAME记录
指向目标 IP地址 另一个域名
解析次数 1次 2次或更多
根域名支持 支持 不支持
典型场景 直接指向服务器 CDN、托管平台
灵活性 低(IP变更需修改) 高(目标域名IP变更无感知)

两种记录的本质区别

A记录:直接指向IP

A记录(Address Record)是最基础的DNS记录,直接把域名映射到IP地址。

css 复制代码
# A记录配置
example.com.    IN    A    185.199.108.153

DNS查询过程很简单:

复制代码
用户查询 example.com → DNS返回 185.199.108.153 → 完成

CNAME:指向另一个域名

CNAME(Canonical Name)记录不直接指向IP,而是指向另一个域名。

objectivec 复制代码
# CNAME配置
blog.example.com.    IN    CNAME    username.github.io.

DNS查询需要两步:

lua 复制代码
用户查询 blog.example.com → DNS返回 username.github.io → 继续查询 → DNS返回 185.199.108.153 → 完成

用流程图表示更清楚:

flowchart LR subgraph A记录解析 A1[用户查询\nexample.com] --> A2[DNS服务器] A2 --> A3[返回IP\n185.199.108.153] end subgraph CNAME解析 C1[用户查询\nblog.example.com] --> C2[DNS服务器] C2 --> C3[返回CNAME\nusername.github.io] C3 --> C4[继续查询] C4 --> C5[返回IP\n185.199.108.153] end

为什么需要CNAME

看起来CNAME多了一次查询,更慢了。那为什么还要用它?

场景一:服务器IP会变

假设你用A记录把域名指向了一台服务器:

css 复制代码
www.example.com.    IN    A    1.2.3.4

有一天服务器迁移了,IP变成了 5.6.7.8,你需要手动改DNS配置。如果有多个域名都指向这台服务器,每个都要改。

用CNAME就不一样了:

objectivec 复制代码
www.example.com.     IN    CNAME    myapp.hosting.com.
blog.example.com.    IN    CNAME    myapp.hosting.com.
api.example.com.     IN    CNAME    myapp.hosting.com.

服务器IP变了,只需要托管平台(myapp.hosting.com)更新它的A记录,你的所有域名自动生效。

场景二:CDN加速

CDN服务商会根据用户位置返回最近的节点IP。这个IP是动态的,不可能用A记录。

csharp 复制代码
# 接入阿里云CDN
static.example.com.    IN    CNAME    example.com.w.kunlunsl.com.

阿里云的CDN会自动把用户引导到最近的节点,你不需要关心具体IP是什么。

场景三:托管服务

GitHub Pages、Vercel、Netlify这类托管平台都要求用CNAME,原因是:

  1. 平台的服务器IP可能随时变化
  2. 平台需要通过域名识别你的站点
  3. 便于实现负载均衡和故障转移

CNAME的限制

根域名不能用CNAME

这是DNS协议的硬性规定。根域名(如 example.com)可能有MX记录(邮件)、NS记录(域名服务器)等,CNAME会与这些记录冲突。

objectivec 复制代码
# 错误:根域名不能设置CNAME
example.com.         IN    CNAME    username.github.io.

# 正确:使用www子域名
www.example.com.     IN    CNAME    username.github.io.

那根域名怎么办?有两个方案:

方案一:用A记录直接指向IP

css 复制代码
example.com.    IN    A    185.199.108.153
example.com.    IN    A    185.199.109.153
example.com.    IN    A    185.199.110.153
example.com.    IN    A    185.199.111.153

方案二:用ALIAS记录(部分DNS服务商支持)

ALIAS是一种"假的CNAME",在DNS服务商那边做了一层转换:

bash 复制代码
# Cloudflare、DNSPod等支持
example.com.    IN    ALIAS    username.github.io.

实际返回给用户的还是IP地址,但配置时可以填域名。

CNAME不能和其他记录共存

同一个域名,如果设置了CNAME,就不能再设置A记录、MX记录等。

erlang 复制代码
# 错误:CNAME和MX冲突
mail.example.com.    IN    CNAME    mailserver.com.
mail.example.com.    IN    MX       10 mailserver.com.

# 正确:分开使用不同子域名
www.example.com.     IN    CNAME    hosting.com.
mail.example.com.    IN    MX       10 mailserver.com.

实战配置示例

GitHub Pages自定义域名

  1. 在仓库根目录创建CNAME文件:

    blog.example.com

  2. 在域名服务商添加CNAME记录:

bash 复制代码
# DNS配置
blog.example.com.    IN    CNAME    username.github.io.
  1. 验证配置:
bash 复制代码
# 查看CNAME记录
dig CNAME blog.example.com

# 输出示例
;; ANSWER SECTION:
blog.example.com.    300    IN    CNAME    username.github.io.
username.github.io.  300    IN    A        185.199.108.153

Vercel部署

bash 复制代码
# www子域名用CNAME
www.example.com.    IN    CNAME    cname.vercel-dns.com.

# 根域名用A记录
example.com.        IN    A        76.76.21.21

Cloudflare CDN

bash 复制代码
# 接入Cloudflare
www.example.com.    IN    CNAME    example.com.cdn.cloudflare.net.

Cloudflare的特殊之处在于它支持"CNAME Flattening",即使是根域名也可以配置CNAME,它会自动转换成A记录返回。

常见问题排查

配置了CNAME但不生效

检查TTL:DNS缓存可能还没更新,等待TTL时间过期。

bash 复制代码
# 查看TTL
dig blog.example.com

# 缩短TTL加快测试(配置时设置)
blog.example.com.    60    IN    CNAME    username.github.io.

检查传播状态

bash 复制代码
# 使用nslookup指定DNS服务器
nslookup blog.example.com 8.8.8.8

# 或用在线工具
# https://dnschecker.org/

循环引用

css 复制代码
# 错误:A指向B,B又指向A
a.example.com.    IN    CNAME    b.example.com.
b.example.com.    IN    CNAME    a.example.com.

DNS服务器会检测循环引用并报错,但排查起来比较麻烦。配置时避免复杂的CNAME链。

HTTPS证书问题

CNAME只是DNS层面的跳转,HTTPS证书需要在最终服务器上配置。

如果你把 blog.example.com CNAME到了 username.github.io,那么:

  • GitHub Pages需要支持你的自定义域名
  • 证书要能覆盖 blog.example.com

GitHub Pages会自动申请Let's Encrypt证书,但需要在仓库设置里开启HTTPS。

决策指南

objectivec 复制代码
需要配置域名解析
├─ 托管在第三方平台(GitHub Pages、Vercel、Netlify)?
│   └─ 用 CNAME 指向平台域名
├─ 接入CDN?
│   └─ 用 CNAME 指向CDN域名
├─ 直接部署在自己的服务器?
│   ├─ IP固定且不会变?
│   │   └─ 用 A 记录
│   └─ IP可能变化?
│       └─ 考虑用 CNAME 指向一个自己控制的域名
└─ 根域名?
    └─ 只能用 A 记录或 ALIAS(如果DNS服务商支持)

小结

  • A记录:域名 → IP,简单直接,但IP变了要手动改
  • CNAME:域名 → 域名 → IP,多一次查询,但更灵活
  • 根域名不能用CNAME,这是DNS协议限制
  • CDN、托管平台都用CNAME,因为它们的IP是动态的

选择的核心原则:如果目标IP可能变化,用CNAME;如果IP固定,用A记录。


如果你觉得这篇文章有帮助,欢迎关注我的 GitHub,下面是我的一些开源项目:

Claude Code Skills (按需加载,意图自动识别,不浪费 token,介绍文章):

全栈项目(适合学习现代技术栈):

  • prompt-vault - Prompt 管理器,用的都是最新的技术栈,适合用来学习了解最新的前端全栈开发范式:Next.js 15 + React 19 + tRPC 11 + Supabase 全栈示例,clone 下来配个免费 Supabase 就能跑
  • chat_edit - 双模式 AI 应用(聊天+富文本编辑),Vue 3.5 + TypeScript + Vite 5 + Quill 2.0 + IndexedDB
相关推荐
7ACE4 小时前
Wireshark TS | 关闭连接和超时重传
网络协议·tcp/ip·wireshark
天天扭码10 小时前
京东前端开发实习生 一面
前端·网络协议·面试
FPGA技术实战12 小时前
基于XADC IP核的FPGA芯片温度读取设计
网络协议·tcp/ip·fpga开发
老蒋新思维12 小时前
范式重构:从场景锚点到价值闭环——AI智能体落地知识产业的非技术视角|创客匠人
网络·人工智能·网络协议·tcp/ip·数据挖掘·创始人ip·创客匠人
ICT技术最前线13 小时前
电信宽带怎么申请公网ip?企业组网避坑指南
网络·网络协议·tcp/ip·电信宽带
老蒋新思维15 小时前
创客匠人万人峰会启示:AI+IP 生态重构,知识变现进入 “共生增长” 时代
网络·人工智能·网络协议·tcp/ip·重构·创始人ip·创客匠人
上海云盾-小余15 小时前
TCP业务DDoS防护专项方案
网络协议·tcp/ip·ddos
apihz16 小时前
反向DNS查询与蜘蛛验证免费API接口详细教程
android·开发语言·数据库·网络协议·tcp/ip·dubbo
古城小栈16 小时前
MCP协议 与 Function Call 的有点分不清楚
网络·网络协议