CDN 下载提速与缓存排查(CDN Cache Bypass & Download Acceleration)
项目:zhiyuan App(在线壳 + 资源包架构,Android WebView 壳)。
2026-08-13 排查「大文件下载慢、CDN 好像没加速」。概念底子见 CDN (Content Delivery Network 内容分发网络) 与 Caching Strategies (缓存策略)。
触发条件
CDN 前置的站点上,大文件(资源包 zip、APK)下载慢,怀疑 CDN 没缓存。
症状
- 15.8MB 资源包、61.5MB APK 下载速度远低于预期,像直连源站。
- 普通图片/地图(
/assets/*)加载正常——说明 CDN 整体在起作用,问题只出在特定大文件上。
根因:源站 Cache-Control 三档
同一站点三类资源,源站给的 Cache-Control 完全不同:
| 资源 | 源站 Cache-Control | CDN 实际行为 |
|---|---|---|
/assets/*(地图/图/JS/CSS) | public, max-age=31536000, immutable | 缓存,但客户端 TTL 被 CDN 规则改写为 max-age=3600 |
资源包 zip(/api/resource-packs/<id>/archive?version=<hash>) | no-store | 完全不缓存,每回源站流式现打(无 Content-Length) |
APK(/download/*.apk) | no-cache(无 ETag) | 每回回源校验,拿不到 304 → 整包重传 |
三个关键判断:
no-store≠no-cache:no-store禁止一切存储,CDN 直接透传;no-cache允许存储但每次必须先回源校验。源站若不发ETag/Last-Modified,校验拿不到 304,退化成整包重传——效果等同没缓存。- 内容寻址 URL 可以
immutable:?version=<hash>这类参数一变内容必变(content-addressed),按完整 URL 缓存是安全的,不会发版后拿到旧文件。 - CDN 会重写源站 Cache-Control:实测源站回
immutable,CDN 回给客户端max-age=3600——CDN 按自己的缓存规则在盖头。所以只改源站头不一定生效,要先查 CDN 缓存规则是否尊重源站头。
安全边界(容易被忽略)
资源包端点在鉴权闸门之后(JWT),但内容本身是公开静态资源。若把它改成可被 CDN 缓存,等于「知道 URL 就能下到 zip」——CDN 缓存命中不会管请求带没带鉴权头。内容公开则可接受,但属于安全边界口径变化,要同步进安全清单(S04 同源)。
解法(2026-08-13 已落地)
- 资源包 zip:源站头
no-store→public, max-age=31536000, immutable+ETag: "<version>"(URL 带 version 指纹,内容寻址,immutable 安全)。端点同时移出鉴权闸门改为公开——内容本就是公开静态资源。EdgeOneFollowOrigin会按源站头缓存。 - APK:改版本化 URL
/download/zhiyuan-app-<version>.apk+public immutable+ETag;固定名旧链接保留为 no-cache 回退(防发版后拿旧包)。resolveApkPath读 manifest 校验版本名,避免任意文件名访问。 - 验证前置:先查 CDN 规则是否尊重源站头——本项目 EdgeOne 是
FollowOrigin(遵循源站)、?version=进完整 URL 缓存键,所以改源站头即生效。若 CDN 是自己盖头(忽略源站 Cache-Control),只改源站没用。
遗留(可选)
- zip 仍是流式现打(无 Content-Length、不支持 Range)。预生成 zip 文件 + 断点续传可做,不阻塞缓存提速。
- 图片扩展名规则把
/assets图片 TTL 压成 3600(EdgeOne 侧配置,未改)。
下次怎么识别
- 大文件慢、小文件正常 → 查源站大文件响应头是不是
no-store/no-cache。 - 改了源站头但线上没变化 →
curl -sI对比源站 vs CDN 返回的Cache-Control,判断 CDN 有没有重写。 - 判断一个 URL 能不能安全长缓存 → 看它是不是内容寻址(URL/参数变 = 内容变)。
相关
- CDN (Content Delivery Network 内容分发网络)
- Caching Strategies (缓存策略)
- zhiyuan App:在线壳 + 资源包架构(base 包首启门禁、地图 WebP 化)
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Web