CDN搭建教程:从零构建一套属于自己的内容分发网络
为什么要自己动手搭一套CDN
网站打开慢、图片转半天、用户还没看到内容就关掉页面——遇到这种情况,多数人的第一反应是买一个商业CDN服务。但对有一定技术基础、又想彻底搞明白分发链路怎么运转的人来说,自己动手搭一套轻量CDN反而更有价值。这篇CDN搭建教程会从需求判断一路讲到上线验证,把中间的配置思路和踩过的坑都摊开说明。
需要先讲清楚一点:自建CDN不是商业CDN的替代品,它更像是一种可控的、成本可估算的方案。理解这一点,后面的每一步配置才不会变成照抄配置文件。
一、先判断:你真的需要自建CDN吗
CDN的本质是把内容提前放到离用户更近的节点上。用户请求资源时不再回源站,而是由边缘节点直接响应,从而缩短网络链路、降低源站压力。商业CDN的优势是节点多、开箱即用,缺点是按流量计费,大文件分发成本会迅速膨胀,而且缓存规则、回源策略这些细节往往只能在前端面板上调整,遇到特殊需求不好落地。
自建CDN更适合这几种场景:源站带宽压力大但用户分布相对集中;手上有多地域的闲置服务器;需要完全掌控缓存键、回源鉴权、访问日志;或者只是想在测试环境里复现CDN的真实行为。如果用户遍布全球、流量巨大且不可预测,自建的成本和运维复杂度很可能高于直接采购,这一点必须提前想明白。
二、整体架构:一条请求要经过哪些环节
一套最小可用的自建CDN由四部分组成:调度层、边缘层、回源层和观测层。
- 调度层:靠DNS智能解析把不同地区的用户指向最近的边缘节点,也可以在前面套一层负载均衡做二次分流。
- 边缘层:运行缓存软件的反向代理服务器,负责命中缓存、回源、压缩、TLS卸载和基础防护。
- 回源层:你的源站,需要配置访问控制,只允许边缘节点回源,避免被绕过。
- 观测层:日志采集与监控,用来判断命中率、回源带宽和节点健康状态。
理解这条链路之后,后面的每一项配置都有明确目的,而不是凭感觉填参数。

三、准备工作:域名、证书与节点
域名规划
建议把静态资源单独拆一个域名,比如 static.example.com。这样做有两个好处:一是缓存策略可以独立设置,不会被主站的动态规则干扰;二是Cookie能自然隔离,避免动态请求携带的Cookie污染缓存键,导致命中率暴跌。图片、JS、CSS走一个域名就够了,视频或大文件如果量比较大,可以再拆一个,方便分开限速和统计。
证书
全站HTTPS已经是默认要求。免费证书用 Let's Encrypt 就足够,通过 acme.sh 或 certbot 自动续期即可。边缘节点数量多的时候,可以采用集中签发再分发到各节点的方式,也可以干脆在边缘做TLS终止,回源走内网或专线,减少握手开销。
节点选择
起步阶段两到三个节点完全够用。选点的原则不是越多越好,而是覆盖主要用户群:华北、华东、华南各一台,或者直接按实际访问日志里的来源分布来定。相比CPU和内存,带宽和磁盘IO对缓存服务更重要,采购时别把预算花错地方。
四、在边缘节点部署缓存服务
缓存软件可以选 Nginx 的 proxy_cache,也可以选 Varnish 或 Apache Traffic Server。Nginx上手成本最低,配置直观,还能顺手把压缩、限速、防盗链一起做掉,本文以它为例。
第一步是定义缓存目录和缓存键。缓存键决定了什么算「同一个资源」,一般用 scheme + host + uri 就够了,不要带Cookie,也不要带无关的查询参数,否则同一个文件会因为参数不同被缓存成几十份,命中率低得可怜。
proxy_cache_path /data/cache levels=1:2 keys_zone=edge:200m
max_size=200g inactive=7d use_temp_path=off;
server {
listen 443 ssl http2;
server_name static.example.com;
location / {
proxy_cache edge;
proxy_cache_key "$scheme$host$uri";
proxy_cache_valid 200 206 7d;
proxy_cache_valid 404 1m;
proxy_cache_lock on;
proxy_cache_use_stale error timeout updating;
proxy_cache_background_update on;
proxy_pass https://origin.example.com;
proxy_set_header Host origin.example.com;
add_header X-Cache-Status $upstream_cache_status;
}
}几个参数值得单独解释。proxy_cache_lock 防止同一个资源被并发回源打爆源站;proxy_cache_use_stale 让节点在回源失败时继续吐旧内容,用户至少不会看到报错页;proxy_cache_background_update 让过期缓存在后台异步更新,避免第一个访问的用户白白等待。而 X-Cache-Status 这个响应头,是后面排查问题的关键线索,一定要加上。
五、回源策略与源站保护
边缘节点配好之后,源站必须做两件事。第一是只放行边缘节点回源,可以在防火墙层做IP白名单,也可以在应用层校验一个密钥请求头,两者叠加更稳妥。第二是给回源请求打标识,比如加一个自定义Header,这样在源站日志里就能清楚区分「用户直连」和「CDN回源」,出问题时定位快得多。
回源还有一个常被忽略的点:Range请求。视频和大文件的断点续传依赖206状态码,如果边缘不支持Range透传,用户拖动进度条就会失败。Nginx默认支持,但要在 proxy_set_header 里保留Range头,并且不要对206响应做整体覆盖式缓存,否则会出现「拖到一半视频卡住」的诡异现象。
六、压缩、图片与大文件分发
文本类资源开启 gzip 或 brotli 能省下大量带宽,但要注意只对文本类型压缩,图片视频压了反而更慢。图片可以做一次格式转换,把JPEG转成WebP或AVIF,体积能降三到五成,这一步放在边缘节点做还是提前在源站处理好,取决于节点的计算资源是否充裕。
大文件分发建议开启分片回源,让边缘节点按块拉取,避免一个几百兆的安装包一次性占满回源带宽。另外,对于每次发布都会变的热门资源,可以做一个预热接口,提前把文件推到各节点,防止上线瞬间流量全部涌向源站。
七、DNS智能解析:把用户送到最近的节点
调度是自建CDN里最容易翻车的一环。简单做法是在DNS服务商处按运营商和地域分线路解析,把不同来源的请求指向不同节点IP。这种方式成本低、配置简单,但对移动网络和长尾地区的判断不够精细。
进阶做法是自己维护一个调度接口,客户端通过302跳转或返回节点列表的方式获取当前最优节点,配合主动探测每个节点的延迟和丢包情况动态调整。要注意TTL不要设得太长,节点故障时才能快速切走,一般把控在几十秒到几分钟之间比较合适。
八、验证:怎么确认它真的在工作
上线后先做三件事。用 curl 连续请求同一个资源,观察 X-Cache-Status 是否从 MISS 变成 HIT;对比直连源站和走CDN的响应时间差异;用不同地区的机器或在线测速工具看解析结果是否指向预期节点。
命中率是最核心的指标。如果静态资源的命中率低于八成,通常是这几个原因:缓存键里混进了随机参数、响应头带了 no-cache、Cookie没有被剥离、或者缓存时间设得太短。逐条排查基本都能解决,而且排查过程本身能帮你把整条链路理解得更透。
九、监控与运维
日常至少要盯四个指标:缓存命中率、回源带宽、节点响应时间和错误率。日志可以用 Filebeat 或 Vector 采集到中心,再配合 Grafana 出图。节点健康检查建议独立于业务进程,避免缓存服务假死但端口还在监听这种「看起来正常其实已废」的情况。
运维里高频操作是缓存刷新。可以做一个内部接口,按URL或目录批量purge,但一定要加鉴权,别把清理入口暴露在公网上——这相当于给攻击者留了一个随时可以打穿源站的后门。
十、安全与常见坑
- 防盗链:用Referer白名单加签名URL,两者结合比单一手段可靠得多。
- 缓存污染:不要把带用户身份的内容缓存下来,登录态接口一律绕开缓存。
- 证书续期:自动化脚本必须加失败告警,证书过期导致整站不可用的情况非常常见。
- 回源风暴:节点刚上线或缓存刚清空时,回源量会陡增,最好在源站前面加一层限流兜底。
如果暂时不想自己维护节点,也可以先用 Cloudflare 这类成熟服务跑通流程,把缓存规则和回源配置验证清楚,再迁移到自建架构上,试错成本会低很多。
十一、成本与扩容思路
自建CDN的成本主要由三块构成:服务器与带宽、证书、以及人力运维。带宽通常是大头,所以节点布局应该跟着用户分布走,而不是盲目堆数量。扩容时优先增加同区域的节点做水平冗余,其次才是开辟新区域,因为新区域的回源链路往往需要重新调优。
真正决定体验的是最后一段链路,也就是节点到用户那几十毫秒。与其建一堆节点却调度混乱,不如先把两三个节点的命中率、回源策略和证书管理做扎实。
结语
这套CDN搭建教程覆盖的是一条完整但克制的路径:两三个节点、一套清晰的缓存规则、一个能用的调度方案。真正的难点不在装软件,而在想清楚哪些内容该缓存、缓存多久、失效时怎么办。把这几个问题定下来,剩下的配置工作只是把它们翻译成参数而已。
