Azure CDN的缓存架构:端点之间到底能不能共享缓存
先给出一个明确的结论:Azure CDN的缓存是按POP(Presence Point,边缘节点)粒度独立存储的,同一个区域内的不同CDN端点,即使源站完全相同、缓存规则完全一致,默认情况下也不会直接共享彼此的缓存内容。每个端点在Azure CDN体系中被视为独立的缓存实体,拥有自己的缓存命名空间,边缘节点在存储和查找缓存对象时,会以端点作为隔离维度。
这个设计初看似乎浪费资源,但实际上有其合理性。不同端点可能配置了不同的缓存规则、不同的源站路径映射、不同的查询字符串处理策略,如果强行让多个端点共享同一份缓存,一旦某个端点的规则更新导致缓存内容与预期不符,排查起来会非常困难。隔离设计保证了每个端点的缓存行为完全由自己的配置决定,可预测性更强。
不过,虽然没有端点间的直接共享,同一区域内的请求仍然可能间接受益于缓存复用。Azure CDN的部分SKU(特别是标准Verizon和高级Verizon版本)在边缘节点缓存未命中时,会先查询区域性父节点,而不是直接回源。这种分层缓存机制在客观上实现了同区域内不同客户端请求之间的缓存复用,只是复用的主体是POP节点而非端点本身。

理解这一点对架构设计很关键:如果你在同一个区域部署了多个端点服务于不同业务线,不要期望它们之间互相"喂"缓存。正确的思路是把同一类内容尽量收敛到同一个端点,通过路径规则来区分业务,让缓存集中在有限的POP节点上,命中率自然就上去了。
提升跨端点场景下缓存复用率的配置策略
既然端点之间不共享缓存,那多个端点并存时的优化重点就变成了两个方向:一是尽量减少端点数量,二是让保留下来的端点尽可能提高单点命中率。下面几个配置手段在实践中效果明显。
统一缓存规则与查询字符串策略
缓存命中与否,取决于请求URL是否与缓存键完全匹配。如果两个端点对查询字符串的处理方式不同,即使URL路径相同,也会产生不同的缓存键。以Microsoft标准版为例,查询字符串缓存行为有三种模式可选:
- 忽略查询字符串:所有带不同参数的请求命中同一份缓存,适合参数不影响内容的场景;
- 使用查询字符串:每个唯一的参数组合都生成独立缓存条目,缓存碎片化严重;
- 忽略指定的查询字符串:只剔除指定的干扰参数(如utm来源标记),其余参数参与缓存键计算,兼顾灵活性与命中率。
对于多个端点共存的情况,建议统一采用"忽略指定的查询字符串"模式,并把分析类参数(utm_source、utm_medium、spm等)统一列入忽略清单,避免同一个文件在边缘节点上被缓存成几十份不同版本。
合理设置缓存过期时间与源站缓存头
Azure CDN的缓存TTL由源站响应头和端点缓存规则共同决定,规则的优先级高于源站头。多端点场景下,如果各个端点对同一资源设置了不同的TTL,会出现同一区域不同端点返回内容版本不一致的问题,尤其在做资源版本更新时容易产生用户看到新旧内容混杂的现象。
推荐的做法是在CDN规则引擎中统一静态资源的TTL,例如图片、字体、带哈希的JS/CSS文件设置30天以上,同时在源站配合使用Cache-Control头作为兜底。下面是一个Nginx源站的典型配置:
# Nginx源站配置示例
location ~* \.(jpg|jpeg|png|gif|webp|woff2)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
location ~* \.(html|json)$ {
expires 5m;
add_header Cache-Control "public, max-age=300";
}注意带内容哈希的静态资源可以放心设置超长TTL,因为文件内容变化时URL本身也会变化,不存在缓存失效问题。而HTML和API响应必须保留较短的TTL,并配合主动刷新机制使用。
利用规则引擎收敛缓存命名空间
高级版Azure CDN的规则引擎(Rules Engine)允许按请求特征改写缓存行为。如果因为业务隔离需求必须保留多个端点,可以在规则引擎中把不同端点的源站路径映射到源站的相同目录结构,保证两个端点请求同一资源时URL完全一致,为将来可能的内容预热和缓存管理打下基础。
分层缓存与缓存预热:同区域缓存复用的真正实现路径
前面提到,端点之间没有直接的缓存共享,但Azure CDN通过分层缓存架构,在区域内实现了事实上的缓存复用。当某个边缘POP收到未命中缓存的请求时,处理流程是这样的:先检查本POP缓存,未命中则查询区域父节点,父节点也没有才会回源。父节点缓存命中后,内容会同时返回给请求的POP并缓存下来。这意味着同区域内第一个用户触发回源后,后续其他POP的未命中请求大多能从父节点拿到数据,源站压力被大幅降低。
使用缓存预热降低冷启动回源
对于发布新版本静态资源这类可预知的场景,主动执行缓存加载(也称为缓存预热)比被动等用户触发更高效。通过Azure CDN的Load Preloaded Content API,可以把指定URL列表的内容提前推送到边缘节点:
// 调用Azure REST API执行缓存预热(伪代码示意)
const endpoint = "https://management.azure.com/subscriptions/{subId}"
+ "/resourceGroups/{rg}/providers/Microsoft.Cdn"
+ "/profiles/{profileName}/endpoints/{endpointName}/load";
const payload = {
contentPaths: [
"/static/js/app.a3f8c2.js",
"/static/css/main.7d91e0.css",
"/images/hero/banner.webp"
]
};
// 使用POST请求提交预热任务,需携带Bearer Token预热任务提交后通常在几分钟内完成。配合多端点场景,可以把关键资源在每个端点上分别预热,确保所有业务入口的用户首访就能命中缓存。需要注意的是预热API有配额限制,单次提交的路径数量和频率都有上限,大批量资源要分批执行。
缓存刷新与多端点一致性
与预热相对的是缓存清除(Purge)。当源站内容更新后,如果存在多个端点引用同一源站,必须对所有相关端点执行Purge操作,否则不同端点的用户会看到不同版本的内容。可以用脚本批量遍历端点列表统一刷新:
import requests
endpoints = ["endpoint-a", "endpoint-b", "endpoint-c"]
for ep in endpoints:
url = (f"https://management.azure.com/subscriptions/xxx"
f"/profiles/cdn-profile/endpoints/{ep}/purge"
f"?api-version=2021-06-01")
requests.post(url, json={"contentPaths": ["/static/js/app.a3f8c2.js"]})迁移到Azure Front Door的考量
值得单独一提的是,微软目前主推的新一代CDN服务Azure Front Door Standard/Premium在缓存架构上做了不少改进,包括更细粒度的缓存规则、内置的缓存命中率监控指标等。如果是新项目,建议直接选择Front Door而不是经典CDN SKU;存量项目在评估缓存共享需求时,也可以把Front Door的规则集作为统一管理多域名的方案,将原本分散的多个CDN端点收敛为单一Front Door配置下的多条路由规则,从架构上消除端点隔离带来的缓存分裂问题。
总结一下:Azure CDN同一区域不同端点间默认不共享缓存,缓存隔离是按端点设计的。真正可行的复用路径有三条:利用区域性父节点实现的分层缓存、通过预热API主动推送内容、以及在架构层面收敛端点数量。配合统一的查询字符串策略和TTL配置,才能在多端点环境下把整体缓存命中率维持在理想水平。