CDN回源是什么意思?回源IP、回源协议与缓存策略详解

用 CDN 的人迟早会遇到"回源"这个词。有的说"回源带宽太高了",有的说"回源配置错了导致网站打不开",还有的把"回源"和"缓存"混在一起说,越听越糊涂。

回源其实是 CDN 工作机制里最关键的一环:CDN 节点上的内容不是凭空来的,当节点没有用户要的内容时,它要回过头去找源站要,这个过程就叫回源。理解回源,才能理解 CDN 为什么有时快有时慢、为什么源站会突然被打、为什么配置错一个选项网站就挂了。这篇文章把回源的概念、涉及的几项配置、缓存策略以及回源带宽的问题一次讲清楚。

一、回源到底是什么

一句话定义:CDN 节点在本地没有可用缓存时,代替用户向源站发起请求、取回内容的过程,叫回源。

把一次 CDN 请求拆开看:用户请求到达边缘节点,节点先查本地缓存。

  • 如果命中(本地有且未过期),直接返回,不涉及源站,这是最快的情况;
  • 如果未命中(本地没有,或内容已过期),节点就要去源站取,这个动作就是回源。取回来之后,节点一方面把内容给用户,另一方面按缓存规则存起来,供后续请求复用。

所以回源是"必然会发生"的,只是频率高低的问题。再好的 CDN 也不可能把所有内容都缓存在所有节点上,第一次访问或者缓存过期后的第一次访问,都要回源。CDN 优化的目标不是"消灭回源",而是"减少不必要的回源"——让回源只发生在真正需要的时候。

回源频率直接决定了三件事:源站压力、回源带宽成本、以及用户等待时间。回源越多,这三项越差。这就是为什么要盯"命中率",命中率高意味着回源少。

# 在源站上看回源请求的频率和来源
tail -f /var/log/nginx/access.log
# 观察日志里请求的来源 IP 是否是 CDN 回源 IP,以及请求的 URL 分布
# 如果同一个 URL 被反复回源,说明缓存没生效或者 TTL 太短

# 统计一段时间内各 URL 的回源次数,找出热点
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

二、回源 IP、回源 Host、回源协议

"回源"配置里有三个绕不开的参数,配错任何一个都会出问题。

回源 IP(回源地址),指的是 CDN 节点去哪个地址取内容,通常是你的源站 IP(或源站域名),以及对应的端口。这里容易出错的地方是:填成了内网 IP、端口和源站监听的端口不一致、或者源站有多个地址但只填了一个。

回源 Host,指的是 CDN 回源时在 HTTP 请求里带上的 Host 头。这个参数非常关键,因为源站(特别是 Nginx)通常是按域名来区分站点的。如果源站上同时跑了多个站点,回源 Host 决定 CDN 拿到的是哪一个站点的内容。如果回源 Host 填成了源站 IP,而源站只认域名,就可能返回默认站点甚至是空的错误页面。

# 在源站上验证回源 Host 是否配置正确
# 用正确的 Host 请求,应该返回正常内容
curl -I -H "Host: www.example.com" http://源站IP/
# 对比用 IP 当 Host,往往返回的是默认站点
curl -I -H "Host: 源站IP" http://源站IP/

# 在 Nginx 源站配置里确认 server_name 匹配
grep -r "server_name" /etc/nginx/conf.d/ /etc/nginx/sites-enabled/ 2>/dev/null

回源协议,指的是 CDN 回源时用 HTTP 还是 HTTPS。常见有三种模式:

回源协议 含义 适用场景
HTTP 回源固定走 80 端口明文 源站不支持 HTTPS,或源站有内网隔离可直接明文
HTTPS 回源固定走 443 加密 源站已配证书、链路需要加密,安全性要求高
跟随客户端(协议跟随) 用户用什么协议,回源就用什么协议 需要端到端一致,但配置失误时容易出问题

选 HTTPS 回源时,CDN 一般会校验源站证书。如果源站用的是自签名证书,可能需要在 CDN 侧开启"忽略证书校验"(不同服务商叫法不同),否则回源握手失败,表现为 502。

如果 HTTPS 回源配错了(比如源站其实只有 80),或者"跟随客户端"但源站不支持某种协议,都会导致回源失败。所以改回源协议前,先在源站上确认对应端口和服务是通的:

# 在源站上确认 80 和 443 都在监听
ss -lntp | grep -E ':80|:443'

# 从其他机器(模拟 CDN 回源)测试源站端口连通性
curl -I --connect-timeout 5 http://源站IP/
curl -Ik --connect-timeout 5 https://源站IP/ -H "Host: www.example.com"

三、回源策略:主备源与择优回源

当业务有多个源站(比如做了多机房、或者主备两台服务器)时,回源策略决定 CDN 优先回哪个源。

主备源:配置一个主源和一个(或多个)备源。正常情况下回源走主源,主源探测失败(比如端口不通、返回 5xx 超过阈值)时自动切到备源。适合"一主一备"的容灾架构,主源故障时用户无感。

择优回源(就近回源):CDN 根据节点与多个源站之间的网络质量、延迟,自动选择当前最优的那个源站回源。适合多活架构,让分布在各地的源站各自服务附近的 CDN 节点,减少跨地域回源。

权重回源:给多个源站配不同权重,按比例分配回源流量。适合做灰度切流或者按比例分流。

策略 逻辑 适用架构
主备源 主源优先,故障自动切备源 一主一备容灾
择优回源 按网络质量选最优源站 多机房多活
权重回源 按比例分配回源流量 灰度、分流

配置多源站时有个常见问题:如果几个源站的数据不一致,用户可能这次访问看到 A 版本、下次看到 B 版本。所以多源站的前提是数据同步做好,否则宁可只配一个源。

四、缓存规则与回源的关系

回源频率高低,本质上由缓存规则决定。缓存规则配得好,回源就少;配得不好,每个请求都回源。缓存规则主要包含几类设置。

缓存过期时间(TTL)。决定内容在节点上缓存多久。设得太短,内容频繁过期、频繁回源;设得太长,内容更新后用户长时间看到旧版本。按内容类型区分是最合理的做法:

内容类型 建议 TTL 理由
带版本/哈希的静态资源 一年或更长 内容不变,文件名一变就换内容
普通图片、字体 三十天到一年 更新频率低,可用文件名版本化
CSS、JS(无版本号) 几小时到几天 需要权衡更新及时性和回源频率
可公开缓存的 HTML 几分钟到几小时 更新较频繁,不能太长
动态接口、登录态页面 不缓存 内容因人而异

忽略 URL 参数。这是提升命中率最关键的一项。如果 URL 里带了无意义的随机参数(比如埋点用的 ?from=xxx&ts=123),默认情况下 CDN 会把它当成不同的 URL,每次都不命中。开启"忽略参数"或"只保留指定参数"后,CDN 会把带参数的 URL 归一化,大幅提升命中率。

未忽略参数:
  用户 A 请求 /img/a.png?ts=111  → MISS,回源
  用户 B 请求 /img/a.png?ts=222  → MISS,回源   (本应命中)
开启忽略参数后:
  两者都被归一化为 /img/a.png    → 第一次 MISS,之后全部 HIT

按状态码缓存。默认可能只缓存 200,但合理配置下还应该考虑:2xx 和 3xx 可以缓存;4xx、5xx 不缓存或者只缓存极短时间。这一项直接关系到会不会"把错误页缓存下来"。

缓存 key 与权重。缓存 key 决定"什么算同一个内容"。除了 URL,还可以把 Host、部分请求头纳入 key。key 设计得越精细,命中率越低但越准确;越粗放,命中率越高但可能张冠李戴。绝大多数场景用默认的"URL + Host"就够了。

是否缓存 Cookie 相关响应。如果响应带着 Set-Cookie,或者用户请求带 Cookie 且 CDN 配置了不缓存带 Cookie 的请求,那这类请求永远不会命中。这是个典型的"命中率被 Cookie 拖垮"的场景。

五、回源带宽与回源频率的优化

回源带宽指的是 CDN 节点从源站拉取内容所消耗的带宽。它和用户看到的"CDN 出口带宽"是两回事:出口带宽是 CDN 发给用户的,回源带宽是 CDN 从源站拉的。理想情况下,回源带宽应该远小于出口带宽,两者之比就是命中率的体现。

如果发现回源带宽很高,说明命中率低,常见原因和优化方向:

  • URL 带随机参数 → 开启忽略参数;
  • TTL 太短 → 适当延长缓存时间;
  • 请求带 Cookie 导致不缓存 → 对静态资源路径关闭 Cookie 缓存限制;
  • 动态内容直接暴露给 CDN → 用动静分离,静态资源独立域名;
  • 缓存被频繁刷新 → 减少手动刷新,改用文件名版本化;
  • 节点太少或调度不合理 → 内容分散、每个节点都要回源,考虑增加节点或调整分层。
# 在源站统计回源请求总量,评估回源压力
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
# 统计各状态码分布,看有没有大量 404/5xx 在被反复回源
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

另一个容易被忽视的点是回源频率限制与合并。短时间内大量相同的回源请求(比如一个热点文件刚好过期,很多节点同时回源),会给源站造成瞬时冲击。好的 CDN 会做"回源合并"(把同一时刻对同一内容的多个回源请求合并成一个),源站侧也可以配合做限流和保护。

六、动态加速场景下的回源

前面讲的都是静态内容的回源。对于动态内容,CDN 默认不做缓存,但很多服务商提供"动态加速"(也叫全站加速),思路不是缓存,而是优化回源链路:CDN 节点到源站之间走服务商自建的优质骨干网、选择更优路径、保持长连接复用,从而减少跨运营商、跨地域带来的延迟和丢包。

动态加速不改变业务逻辑,源站还是要实时处理每个请求,它的收益来自链路质量而不是缓存。这类场景下"回源"是常态,优化的重点从"减少回源次数"变成了"让每次回源更快更稳"。

判断要不要开动态加速:如果用户的 TTFB(首字节时间)里,网络往返占了很大比例,而源站本身处理很快,那链路优化收益明显;如果源站处理本身就慢(数据库慢查询、程序逻辑重),那先优化源站比开动态加速更有效。

# 用 curl 拆解 TTFB 的构成,判断瓶颈在链路还是源站
curl -o /dev/null -s -w 'dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n' https://www.example.com/
# connect 到 ttfb 之间的差值主要是源站处理时间
# 如果 connect 本身就很慢,说明链路质量是瓶颈

常见问题

Q:回源带宽和 CDN 出口带宽哪个大?
正常情况下回源带宽应该远小于出口带宽,因为大部分请求都被缓存命中了。如果回源带宽接近甚至超过出口带宽,说明命中率很低,要查缓存规则。

Q:回源一定要用 HTTPS 吗?
不一定。如果源站不支持 HTTPS,或者 CDN 到源站是内网/专线,用 HTTP 回源也可以。但如果对链路安全有要求,建议用 HTTPS 回源,并处理好源站证书校验。

Q:回源 Host 填 IP 可以吗?
技术上可以,但前提是源站只有一个站点或者 IP 就能匹配到正确站点。多站点环境一定要填对的域名,否则会拿到错误的站点内容。

Q:为什么第一次访问慢,刷新几次就快了?
第一次是回源,CDN 要去源站取,自然慢;取回来缓存后,后续请求直接命中缓存就快了。这是正常现象,不一定是问题。

Q:缓存过期时间设长了,内容更新怎么办?
给静态资源文件名加版本号或内容哈希,更新时换个文件名,新文件名自然不回源旧内容,旧缓存自然淘汰。这样既能设长缓存,又不影响更新。

总结

回源是 CDN 节点在本地没有可用缓存时,代替用户向源站取内容的过程。它必然会发生,优化目标是减少不必要的回源,而不是消灭回源。

回源的三个核心参数是回源 IP、回源 Host、回源协议。回源 Host 决定源站返回哪个站点的内容,多站点环境尤其要配对;回源协议要和源站实际支持的协议一致,否则会回源失败。

有多源站时,可以用主备源做容灾、择优回源做多活、权重回源做分流,但前提是各源站数据一致,否则会出现内容跳变。

缓存规则直接决定回源频率:TTL 要按内容类型分层设置,忽略 URL 参数是提升命中率最有效的一招,按状态码缓存能防止缓存错误页,Cookie 相关的缓存限制要小心处理。

回源带宽高就是命中率低的信号,逐项排查参数、TTL、Cookie、刷新频率和节点分布。动态内容虽然默认不缓存,但可以通过动态加速优化回源链路,判断瓶颈在链路还是源站,用 curl 拆解 TTFB 就能看清。