一次CDN切换到底要动哪些东西
很多人以为CDN切换就是改一下域名的CNAME记录,指向新CDN的加速域名就完事了。实际上一个完整的CDN切换至少要覆盖这几个维度:
| DNS解析 | CNAME记录从旧CDN域名改为新CDN域名,这是最核心的一步 |
| 回源配置 | 源站IP/域名、回源协议(HTTP/HTTPS)、回源HOST头,三个参数一个不对用户就打不开 |
| HTTPS证书 | 新CDN上需要部署SSL证书,如果证书过期或域名不匹配,浏览器直接报安全警告 |
| 缓存规则 | 静态文件(JS/CSS/图片)缓存时间、目录级缓存、不缓存的动态路径,新CDN上要逐条重新配置 |
| 防盗链/鉴权 | Referer白名单、URL鉴权key、IP黑白名单,漏掉一条资源就被盗用或访问被拦截 |
| 性能配置 | Gzip/Brotli压缩、HTTP/2/3、智能压缩、Range回源、分片大小 |
| 监控告警 | 流量、带宽、状态码、命中率的监控阈值需要在新CDN上重新设置 |
一、三个前置动作,比切换本身更重要
切换CDN翻车的案例里,80%不是切换过程出了问题,而是切换之前该做的工作没做。下面三个前置动作花半小时做完,切换时基本不会出大事。
动作一:导出旧CDN的全部配置
绝大多数CDN厂商不提供一键导出全部配置的功能。你需要手动逐项记录下来,做成一张配置清单表:加速域名 → 源站信息 → 缓存规则(每个目录/文件类型的过期时间)→ HTTPS证书到期时间 → 防盗链规则 → IP黑白名单 → 回源超时时间 → 带宽上限。这份清单有两个作用:一是迁移到新CDN时逐项对照配置,二是万一新CDN出问题需要回滚时,旧CDN的配置还在手里。
动作二:在新CDN上预配并验证
在新CDN上添加加速域名、配置源站、上传SSL证书、设置缓存规则。配完之后不要急着切DNS,先做本地hosts验证:在本机hosts文件里把域名指向新CDN的CNAME对应IP,然后用浏览器访问看是否正常。注意检查HTTPS证书是否生效、静态资源是否命中缓存、动态接口是否正常回源。全部通过之后再往下走。

动作三:把DNS的TTL提前降到最低
DNS记录有一个TTL(Time To Live)值,决定了各地DNS服务器缓存这条记录多久。如果你切换CNAME时TTL还是默认的600秒(10分钟)甚至更长,那么从你改完记录到最后所有用户都解析到新CDN,可能还要再等10-30分钟——这段时间里一部分用户走旧CDN,一部分走新CDN,如果旧CDN在你切换后立刻停掉了,那些还没刷新DNS的用户就彻底打不开网站了。正确做法:切换前24小时,把CNAME记录的TTL降到60秒或更低。这样切换时DNS变更几乎立即在全球生效。
二、五种切换方式,看域名数量选
切换方式的选择取决于你手里有多少个域名要切。1个域名和50个域名,操作方法完全不同。
| 切换方式 | 适合规模 | 耗时(含验证) | 风险等级 | 核心操作 |
|---|---|---|---|---|
| 手动逐个切换 | 1-5个域名 | 30分钟-1小时 | 低 | 登录DNS控制台,逐个改CNAME |
| CDN厂商自带迁移工具 | 1-20个域名 | 20-40分钟 | 低 | 腾讯云/阿里云提供"一键导入"迁移功能,可导入其他厂商CDN配置 |
| DNS API批量脚本 | 10-50个域名 | 10-20分钟 | 中 | Python调用DNS服务商API批量修改CNAME记录 |
| CDN厂商API批量配置 | 20-100个域名 | 30-60分钟 | 中 | 调用新CDN的API批量添加域名+配置,再调DNS API切CNAME |
| Terraform IaC | 50个域名以上 | 配置1-2小时,执行10分钟 | 高 | Terraform声明式管理CDN+ DNS资源,plan→apply批量生效 |
三、域名不多(10个以内):DNS API批量脚本就够了
如果你有10个以内的域名需要切CDN,没必要上Terraform。写一个Python脚本,调用DNS服务商(Cloudflare、阿里云DNS、腾讯云DNSPod、GoDaddy等)的API,批量修改CNAME记录,20行代码就能搞定。
以Cloudflare DNS API为例,把下面脚本里的API Token和Zone ID换成你自己的,填上域名和新CNAME列表,跑一次就全部切换完成:
import requests# Cloudflare API配置API_TOKEN = "你的Cloudflare API Token"ZONE_ID = "你的Zone ID"HEADERS = {"Authorization": f"Bearer {API_TOKEN}", "Content-Type": "application/json"}# 域名和对应的新CDN CNAMEdomains = [{"name": "www.example.com", "new_cname": "new-cdn.example.cdn.com"},{"name": "api.example.com", "new_cname": "new-cdn.example.cdn.com"},{"name": "cdn.example.com", "new_cname": "new-cdn.example.cdn.com"},]def get_dns_record_id(domain_name):"""获取指定域名的CNAME记录ID"""url = f"https://api.cloudflare.com/client/v4/zones/{ZONE_ID}/dns_records?type=CNAME&name={domain_name}"r = requests.get(url, headers=HEADERS)records = r.json()["result"]return records[0]["id"] if records else Nonedef update_cname(domain_name, record_id, new_cname):"""更新CNAME记录"""url = f"https://api.cloudflare.com/client/v4/zones/{ZONE_ID}/dns_records/{record_id}"data = {"type": "CNAME", "name": domain_name, "content": new_cname, "ttl": 60, "proxied": False}r = requests.put(url, headers=HEADERS, json=data)return r.json()["success"]for d in domains:record_id = get_dns_record_id(d["name"])if record_id:ok = update_cname(d["name"], record_id, d["new_cname"])print(f"{'OK' if ok else 'FAIL'}: {d['name']} -> {d['new_cname']}")else:print(f"SKIP: {d['name']} 无CNAME记录")
注意:如果用的是阿里云DNS、腾讯云DNSPod或GoDaddy,API调用方式不同但逻辑完全一样——先查记录ID,再PUT更新content字段。各家API文档都很清楚,照着改就行。
四、域名多了(20-100个):CDN厂商API + 配置组
当域名数量上到几十个,手动写DNS切换脚本就不够了——更大的工作量在新CDN上的域名添加和配置。每个域名都要配源站、缓存规则、HTTPS证书、防盗链,几十个域名手动配下来可能要一整天。
目前主流的CDN厂商都提供了批量管理能力:
阿里云CDN · 配置组
阿里云CDN支持"配置组"功能。先创建一个配置组,在里面定义好缓存规则、回源配置、HTTPS设置、IP黑白名单等。然后把多个域名批量加入这个配置组,所有域名自动继承配置组的设置。新增域名时只要加入配置组,不用从头配一遍。支持通过API(BatchSetCdnDomainConfig)批量操作。
腾讯云CDN · 域名批量导入
腾讯云CDN控制台支持批量导入域名。准备好CSV文件(域名、源站、业务类型、加速区域),一次导入最多50个域名。CDN配置也可以通过API(UpdateDomainConfig)批量下发。腾讯云还提供了"从其他CDN迁移"的向导,可以导入阿里云CDN的配置。
又拍云 · 统一配置模板
又拍云CDN通过"服务"概念管理加速域名,一个服务下可以绑定多个域名,共享同一套缓存规则、回源配置、HTTPS设置。创建好模板服务后,新域名只需绑定到服务即可,配置自动生效。
Cloudflare · Bulk Redirect + Rulesets API
Cloudflare通过Rulesets API可以批量管理多个域名的缓存规则、WAF规则、重定向规则。配合Workers还可以实现更灵活的批量逻辑。Cloudflare的Terraform Provider是同类中最成熟的,适合IaC管理。
最佳实践:如果你要在新CDN上添加50个域名,不要一个一个配。先在第一个域名上调好所有配置(缓存规则、回源HOST、HTTPS、防盗链),确认跑通后,把这个域名的配置导出为模板。后续49个域名直接用API传入模板参数批量创建。阿里云和腾讯云都支持这种"先调一个,再复制"的模式。
五、域名数量过百:Terraform基础设施即代码
当CDN域名数量超过100个,或者需要频繁切换、需要在多个环境(测试/预发/生产)之间保持一致配置时,手动操作和脚本都变得不可靠。Terraform(基础设施即代码)是这类场景的标准方案。
用Terraform管理CDN的核心优势:
声明式管理
你在.tf文件里写"这个域名应该配这些缓存规则",Terraform负责把实际状态对齐到目标状态。不怕手动改漏了某个配置。
plan预览变更
terraform plan会告诉你这次apply会新增哪些域名、修改哪些配置、删除哪些记录。切换前先看一眼plan,避免误操作。

版本控制
CDN配置存在Git里。谁改了什么、什么时候改的、为什么改,git log一目了然。出了事故可以快速回滚到上一个版本。
以阿里云CDN为例,Terraform配置长这样——定义了加速域名、源站信息、缓存过期时间、HTTPS证书:
# 批量定义域名和源站variable "cdn_domains" {type = map(object({source_content = stringsource_port = number}))default = {"www.example.com" = { source_content = "1.2.3.4", source_port = 443 }"api.example.com" = { source_content = "1.2.3.5", source_port = 443 }"cdn.example.com" = { source_content = "1.2.3.6", source_port = 443 }}}# 批量创建CDN域名resource "alicloud_cdn_domain_new" "domains" {for_each = var.cdn_domainsdomain_name = each.keycdn_type = "web"scope = "domestic"sources {content = each.value.source_contenttype = "ipaddr"port = each.value.source_portpriority = 20}certificate_config {cert_type = "upload"}}# 批量配置缓存规则resource "alicloud_cdn_domain_config" "cache" {for_each = var.cdn_domainsdomain_name = each.keyfunction_name = "set_req_host_header"function_args {arg_name = "domain_name"arg_value = each.key}}
Terraform也支持Cloudflare和腾讯云CDN:Cloudflare的Terraform Provider(cloudflare_record用于DNS,cloudflare_ruleset用于缓存规则)是最完善的;腾讯云的tencentcloud_cdn_domain资源也覆盖了域名添加、源站配置、缓存规则等常用操作。如果团队已经在用Terraform管理其他云资源,把CDN也纳入IaC管理是最省心的选择。
六、切换过程中最容易翻车的三个环节
工具和方法都清楚了,但在实际切换时,下面这三个环节出的问题最多。
环节一:HTTPS证书没同步
这是CDN切换翻车的头号原因。新CDN上加速域名配好了、缓存规则也设了、DNS也切过去了,结果用户打开网站显示"您的连接不是私密连接"——因为SSL证书没在新CDN上部署,或者部署了但还没生效。
正确做法:在切DNS之前,先在新CDN上上传SSL证书(或使用CDN提供的免费证书),用本地hosts验证HTTPS访问正常。证书到期时间也要记录下来——如果证书只剩一个月到期,切过去之后很快又要更新,不如提前续好再切。
环节二:回源HOST头配错
不同CDN对"回源HOST"的处理方式不一样。有的默认用加速域名作为回源HOST,有的默认用源站IP。如果你的源站(比如Nginx)靠HOST头来区分不同站点(虚拟主机),回源HOST配错了,CDN回源请求到了正确的服务器但命中了错误的站点,返回的内容完全不对。
正确做法:从旧CDN上找到回源HOST的配置,在新CDN上原样设置。如果源站是IP直连且只有一个站点,一般不用改;如果源站一个IP绑了多个域名,回源HOST必须指定为正确的域名。
环节三:DNS切换后没有灰度验证
很多人切换CDN的流程是:改CNAME → 等10分钟 → 访问一下首页能打开 → 收工。但首页能打开不代表所有功能正常。图片CDN域名、API接口、WebSocket连接、文件下载——每一个功能模块依赖的域名可能都不一样,只验证首页远远不够。
正确做法:提前准备一份验证清单:首页加载、静态资源(JS/CSS/图片)加载、HTTPS证书、API接口响应、登录/注册流程、文件上传/下载、视频播放。DNS切换后逐一验证,全部通过才算切换完成。如果有条件,先用一个测试子域名完整验证一轮,再切主域名。
七、不同规模网站的工具组合建议
根据域名数量和团队技术能力,给出三种组合方案:
| DNS切换 | DNS服务商控制台手动改CNAME,或Python脚本批量 |
| CDN配置 | 新CDN控制台手动添加,第一个域名调通后复制配置 |
| 验证 | 本地hosts + 浏览器逐个域名访问 |
| 耗时 | 1-2小时(含前置准备) |
| DNS切换 | Python脚本调用DNS API批量修改CNAME |
| CDN配置 | CDN厂商配置组/模板 + API批量创建域名 |
| 验证 | Python脚本批量curl + 状态码检查 |
| 耗时 | 半天(含脚本编写和批量验证) |
| DNS切换 | Terraform管理DNS记录(cloudflare_record / alicloud_dns_record) |
| CDN配置 | Terraform CDN Provider批量管理域名+配置,Git版本控制 |
| 验证 | 自动化测试脚本 + 监控系统告警(Grafana/Prometheus) |
| 耗时 | Terraform配置1-2天,执行切换10-30分钟 |
八、切换后必须做的四件事
DNS切完了、页面能打开了——到这一步很多人就觉得大功告成了。但下面四件事不做,过两天可能出更大的问题。
1. 监控CDN命中率
新CDN上线后头24小时,命中率通常会比较低(缓存还没热起来)。但如果48小时后命中率仍然远低于旧CDN的水平(比如旧CDN 95%命中率,新CDN只有60%),说明缓存规则配置有问题——可能某些该缓存的文件类型没配缓存规则,或者缓存时间设得太短。
2. 检查源站负载
CDN切换后,如果命中率低或者回源配置有误,大量请求会穿透CDN直接打到源站。盯着源站的CPU/带宽/连接数,如果切换后源站负载明显上升,说明CDN没有正确承担流量,需要立刻排查回源和缓存规则。
3. 保留旧CDN至少72小时
切换后不要立刻删除旧CDN的配置和域名。至少保留72小时(最好一周)。万一新CDN出问题,改回CNAME到旧CDN只需要几分钟。如果你已经把旧CDN的域名删了、证书吊销了,回滚就要从头配置,至少半小时起步。
4. 更新外部系统里的CDN域名
如果你的业务系统里有硬编码的CDN域名(比如OSS回源白名单里写了旧CDN的回源IP段、WAF里配置了旧CDN的CNAME白名单、业务代码里拼接了旧CDN的加速域名),必须逐项更新。忘了改OSS白名单,CDN回源请求被OSS拒绝,用户看到的全是403。
最后说一点
CDN切换这件事,域名少的时候花一两个小时手动操作就够了;域名一旦上了两位数,一定要用脚本或Terraform,靠人工一行一行改不仅慢,更容易漏配置。最大的坑其实不在切换那一瞬间,而在切换之后——旧CDN停得太快、证书没同步、回源HOST不对、源站被突然增加的直连流量打崩。把前置验证做足、切换后保留旧CDN至少三天、盯着监控看24小时,这三条做到了,切换CDN基本不会出大问题。
