A 记录、CNAME 和 Nginx 到底是干什么的
很多人第一次把后端服务部署到公网时,会遇到一串看起来很分散的词:
text
域名、A 记录、CNAME、Nginx、HTTPS、反向代理
它们好像都和"网站能不能访问"有关,但每个概念到底负责哪一段,经常容易混在一起。
这篇文章不假设你有某个具体项目,也不要求你提前懂服务器。我们用一个虚构域名 example.com 来讲清楚:
- A 记录解决什么问题
- CNAME 为什么不是"指向 IP"
- Nginx 为什么常放在后端服务前面
- "反向代理"到底反向在哪里
- 一次完整访问请求是怎么从浏览器或 App 走到后端程序的
先看一条完整链路
假设你做了一个 App,后端接口地址是:
text
https://api.example.com/analyze
用户点击按钮后,请求大概会经历这条链路:
text
App / Browser
|
| 访问 https://api.example.com/analyze
v
DNS
|
| 把 api.example.com 解析成服务器 IP
v
Server
|
| 443 端口,HTTPS
v
Nginx
|
| 转发到本机后端服务
v
Backend API
这条链路可以先记成一句话:
text
DNS 负责"找到哪台服务器",Nginx 负责"到了服务器以后交给哪个程序"。
接下来我们拆开看。
DNS 是什么:域名不是地址,而是名字
用户访问的是:
text
api.example.com
但网络真正连接服务器时,需要的是 IP 地址,比如:
text
203.0.113.10
DNS 的作用就是把人容易记的域名,翻译成机器能连接的 IP。
可以把 DNS 想成互联网的通讯录:
text
api.example.com 住在哪里?
DNS 回答:它在 203.0.113.10
DNS 里有很多记录类型,最常见的两个就是 A 记录和 CNAME。
A 记录:这个域名直接对应哪个 IP
A 记录的作用非常直接:
text
域名 -> IPv4 地址
例如:
text
api.example.com A 203.0.113.10
意思是:
text
有人访问 api.example.com 时,请告诉他 IP 是 203.0.113.10。
如果你有自己的云服务器或 VPS,并且知道它的公网 IP,A 记录就是最常见的配置方式。
在很多域名控制台里,你会看到类似这样的配置:
text
Type: A Record
Host: api
Value: 203.0.113.10
这里的 api 不是完整域名,而是子域名前缀。假设你的主域名是 example.com,那么:
text
Host = api
实际代表:
text
api.example.com
还有一个常见写法是:
text
Host = @
@ 代表主域名本身,也就是:
text
@ = example.com
所以:
text
A @ 203.0.113.10
A api 203.0.113.10
表示:
text
example.com -> 203.0.113.10
api.example.com -> 203.0.113.10
一句话:A 记录就是给域名直接指定 IP。
CNAME:这个域名跟着另一个域名走
CNAME 很多人容易误解。
它不是:
text
域名 -> IP
而是:
text
域名 -> 另一个域名
例如:
text
www.example.com CNAME example.com
意思是:
text
www.example.com 不自己记录 IP,它跟着 example.com 走。
解析时会变成这样:
text
www.example.com
|
| CNAME
v
example.com
|
| A
v
203.0.113.10
也就是说,访问 www.example.com 时,DNS 会先发现:
text
www.example.com 是 example.com 的别名
然后继续去查:
text
example.com 的 IP 是多少?
最后拿到 IP。
CNAME 的核心作用是:让一个域名跟着另一个域名走。
为什么 CNAME 可以"只改一处"
假设一开始你这样配:
text
A example.com 203.0.113.10
CNAME www.example.com example.com
此时:
text
example.com -> 203.0.113.10
www.example.com -> example.com -> 203.0.113.10
后来你换了一台服务器,新 IP 变成:
text
203.0.113.20
你只需要改主域名那条 A 记录:
text
A example.com 203.0.113.20
www.example.com 那条 CNAME 不需要动,因为它从来没有保存过 IP。它保存的是:
text
我跟 example.com 走。
所以新的解析链路自动变成:
text
www.example.com
|
| CNAME
v
example.com
|
| A
v
203.0.113.20
这就是 CNAME 的价值:它表达的是"跟随关系",不是"最终地址"。
一个容易记的类比
A 记录像这样写地址:
text
张三住在:深圳市南山区某小区 3 栋 502
CNAME 像这样写地址:
text
张三住在:跟李四同一个办公室
如果李四换办公室了,张三这条记录不用改,因为张三记录的是"跟李四走"。
在 DNS 里:
text
A 记录 = 直接写最终地址
CNAME = 写"跟谁走"
什么时候用 A,什么时候用 CNAME
可以用一个简单判断:
text
你知道最终服务器 IP,并且这个 IP 由你管理 -> 用 A 记录
你只知道另一个平台给你的域名,不想管它背后的 IP -> 用 CNAME
常见场景:
| 场景 | 常用配置 |
|---|---|
| 自己的 VPS 或云服务器 | A 记录 |
api.example.com 指向自己的后端服务器 |
A 记录 |
www.example.com 跟随 example.com |
CNAME |
| 博客部署在 Vercel / Netlify / GitHub Pages | CNAME |
| CDN 提供一个加速域名 | CNAME |
例如你把博客部署到某个托管平台,平台给你一个地址:
text
my-blog.hosting-platform.com
你想让用户访问:
text
blog.example.com
就可以配置:
text
CNAME blog.example.com my-blog.hosting-platform.com
这样托管平台后面换多少服务器、多少 IP,都由它自己管理。你的域名只负责"跟着这个平台给的域名走"。
DNS 配好了,为什么还需要 Nginx
DNS 只解决第一步:
text
api.example.com 应该去哪个 IP?
但请求到了服务器以后,还会遇到新的问题:
text
这台服务器上可能有多个程序。
这个请求应该交给谁?
HTTPS 证书谁来处理?
后端服务要不要直接暴露在公网?
这时就轮到 Nginx 出场。
可以把 Nginx 想成服务器门口的接待员:
text
用户请求
|
v
Nginx:先接住
|
v
后端程序:真正处理业务
后端程序可能只监听本机端口:
text
127.0.0.1:8080
这个地址外部用户无法直接访问。外部用户只访问:
text
https://api.example.com
Nginx 收到请求后,再把它转给本机后端:
text
api.example.com
|
v
Nginx
|
v
127.0.0.1:8080
这就是 Nginx 最常见的作用之一:反向代理。
但 Nginx 不只是"转发请求"这么简单。实际部署里,它更像服务器的统一入口,把很多原本可以写在后端程序里的基础能力,集中放在入口层处理。
Nginx 常见的几个作用
1. 统一入口
一台服务器上可能同时跑着多个服务:
text
官网前端:127.0.0.1:3000
后端 API:127.0.0.1:8080
管理后台:127.0.0.1:9000
外部用户不应该记这些端口。更常见的方式是让用户只访问域名:
text
https://example.com
https://api.example.com
https://admin.example.com
Nginx 根据不同域名或路径,把请求分发给不同程序:
text
example.com -> 127.0.0.1:3000
api.example.com -> 127.0.0.1:8080
admin.example.com -> 127.0.0.1:9000
这样外部世界看到的是一组清晰的域名,服务器内部怎么跑、端口怎么分配,都可以藏在 Nginx 后面。
2. 处理 HTTPS 证书
生产环境通常需要 HTTPS。证书可以由后端程序自己处理,但更常见的是交给 Nginx。
这样后端程序只需要处理普通 HTTP 请求,不用关心证书文件、TLS 握手、续期等细节。
text
用户 -> HTTPS -> Nginx -> HTTP -> 后端程序
对小团队和个人项目来说,这个分工很舒服:Nginx 管"安全连接",后端管"业务逻辑"。
3. 隐藏后端程序
如果后端服务直接暴露公网,用户可以直接访问:
text
http://服务器IP:8080
这不是不能用,但生产环境通常不这么做。
更常见的方式是:
text
公网只开放 80 / 443
后端只监听 127.0.0.1:8080
也就是说,外部只能访问 Nginx,不能绕过 Nginx 直接访问后端。这样后端服务的端口、进程、内部结构都不会直接暴露给公网。
4. 服务静态文件
Nginx 很擅长返回静态资源,比如:
text
HTML
CSS
JavaScript
图片
下载文件
如果只是返回一个图片或前端打包后的文件,让 Nginx 直接处理通常更简单、更快,不需要每次都经过后端程序。
例如一个网站可以这样分工:
text
/assets/logo.png -> Nginx 直接返回文件
/api/user -> Nginx 转发给后端 API
5. 限制请求和保护后端
Nginx 还可以在请求进入后端之前做一些基础保护:
text
限制上传文件大小
限制请求频率
设置超时时间
拒绝异常请求
记录访问日志
比如上传简历、图片、视频时,可以在 Nginx 里限制最大请求体:
nginx
client_max_body_size 10m;
这样过大的请求会先被 Nginx 拦下来,不会直接压到后端服务。
6. 负载均衡
当后端服务不止一个实例时,Nginx 还可以把请求分发到多个后端:
text
-> API 1: 127.0.0.1:8081
用户请求 -> Nginx
-> API 2: 127.0.0.1:8082
-> API 3: 127.0.0.1:8083
这样单个后端进程压力会小一些,某个实例出问题时,也更容易做切换。
早期个人项目可能用不上负载均衡,但知道 Nginx 有这个能力,有助于理解它为什么常被放在服务器最前面。
为什么叫反向代理
"代理"这个词容易让人想到 VPN。
VPN 或公司网络代理,通常是这样的:
text
用户 -> 代理 -> 外部网站
代理站在用户这一边,代表用户出去访问网站。这叫正向代理。
反向代理正好反过来:
text
用户 -> Nginx -> 后端服务
Nginx 站在服务器这一边,代表后端服务接收用户请求。
所以区别不是"请求有没有发送",而是:
text
正向代理:代理代表客户端。
反向代理:代理代表服务器。
用户访问 https://api.example.com,他并不知道后面真正处理请求的是哪个程序、哪个端口、甚至哪台机器。用户只看到 Nginx 暴露出来的统一入口。
Nginx 和 HTTPS 的关系
生产环境通常希望用户访问的是 HTTPS:
text
https://api.example.com
HTTPS 需要证书。证书要证明:
text
这台服务器确实有资格代表 api.example.com。
很多后端程序可以自己处理 HTTPS,但实际部署时,更常见的做法是让 Nginx 处理证书和加密。
链路大概是:
text
Browser / App
|
| HTTPS,加密
v
Nginx
|
| HTTP,本机通信
v
Backend API
也就是说:
- 外部用户到 Nginx:HTTPS,加密
- Nginx 到后端程序:通常是本机 HTTP
这叫 TLS termination,可以简单理解为:
text
HTTPS 在 Nginx 这一层处理完。
一个简化版 Nginx 配置长这样:
nginx
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
不需要一开始记住每一行,只要抓住三句:
text
listen 443 ssl:Nginx 接 HTTPS。
server_name api.example.com:这个配置负责哪个域名。
proxy_pass http://127.0.0.1:8080:请求转发给哪个后端。
A 记录、CNAME、Nginx 怎么串起来
假设我们有三个域名需求:
text
example.com 官网
www.example.com 官网别名
api.example.com 后端 API
DNS 可以这样配:
text
A @ 203.0.113.10
A api 203.0.113.10
CNAME www example.com
对应关系是:
text
example.com -> 203.0.113.10
api.example.com -> 203.0.113.10
www.example.com -> example.com -> 203.0.113.10
请求 API 时:
text
App
|
| https://api.example.com/analyze
v
DNS: api.example.com -> 203.0.113.10
|
v
Server
|
v
Nginx
|
v
Backend API
访问 www 时:
text
Browser
|
| https://www.example.com
v
DNS: www.example.com -> example.com -> 203.0.113.10
|
v
Server
|
v
Nginx
|
v
Website
DNS 和 Nginx 的分工非常清楚:
text
DNS:先把域名带到正确的服务器。
Nginx:再作为服务器入口,处理 HTTPS、转发、静态文件、日志和基础保护。
常见误区
误区一:CNAME 可以指向 IP
不可以。
错误写法:
text
CNAME www 203.0.113.10
正确写法:
text
CNAME www example.com
如果你要直接指向 IP,用 A 记录。
误区二:配置了 DNS,网站就一定能访问
不一定。
DNS 只负责把域名解析到服务器。到了服务器以后,还要看:
- Nginx 有没有监听 80 / 443
- HTTPS 证书有没有配置
server_name是否匹配当前域名- 后端服务是否真的在运行
proxy_pass是否转发到了正确端口
DNS 配对了,但 Nginx 没配好,网站一样打不开。
误区三:www.example.com 和 example.com 天然一样
不一样。
它们是两个不同的域名。你需要显式配置:
text
CNAME www example.com
或者:
text
A www 203.0.113.10
否则主域名能访问,不代表 www 一定能访问。
误区四:后端程序必须直接暴露公网端口
不一定。
更常见的生产部署是:
text
公网 HTTPS -> Nginx -> 本机后端端口
这样后端程序不需要直接暴露给公网,证书、转发、限流、日志等基础能力可以放在 Nginx 这一层处理。
总结
把这些概念压缩成几句话:
text
A 记录:域名直接指向 IP。
CNAME:域名指向另一个域名,跟着它走。
DNS:负责把域名带到哪台服务器。
Nginx:负责服务器入口,处理 HTTPS、转发、静态资源、日志和基础保护。
反向代理:Nginx 站在服务器这一边,替后端接收请求。
HTTPS:通常由 Nginx 处理证书和加密。
如果你在部署一个普通 Web 或 App 后端,可以按这个顺序排查:
text
1. 域名有没有 DNS 记录?
2. A 记录是否指向正确服务器 IP?
3. CNAME 是否最终能追到一个 A 记录?
4. Nginx 是否监听了正确域名和端口?
5. HTTPS 证书是否覆盖了这个域名?
6. Nginx 是否把请求转发给了正确的后端服务?
7. 上传大小、超时、日志等入口层配置是否符合业务需要?
只要这条链路理顺了,A 记录、CNAME、Nginx 就不再是一堆孤立的配置项,而是一次请求从用户设备走到后端程序的不同路标。