1.CDN缓存
2.解决方案
1.CDN缓存
csharp
复制代码
CDN并不会主动把旧包和新包放在一起, 所谓的"新旧包混杂", 本质是相同文件名的前提下, CDN不同边缘节点的缓存状态不
一致 ------ 有的节点存着旧包, 有的节点拉取了新包, 用户访问不同节点就拿到不同版本, 从用户视角看就像是"混在一起了"
csharp
复制代码
1).前提: 只针对"同名文件", 比如都是hotupdate.zip
如果热更包文件名不同(v1.0.0和v1.0.1), CDN会把它们当成完全不同的两个文件, 各节点会独立缓存, 根本不存在混杂,这
也是为什么改文件名能从根源解决问题
混包只发生在"文件名不变, 只替换源站文件"的场景下, 核心原因: 3个CDN特性导致节点缓存状态不一致
csharp
复制代码
a.每个CDN节点是"独立的小仓库", 互相不通气
全国的CDN边缘节点彼此之间没有数据同步, 北京节点存了什么版本、缓存有没有过期, 上海节点完全不知道, 每个节点只管
自己的库存和计时
源站把hotupdate.zip从v1换成v2后, 不会主动通知所有节点"赶紧换包", 节点们只能靠自己的缓存过期规则判断是否需要
更新
csharp
复制代码
b.缓存过期时间"节点各自计时", 起点完全不同
节点的缓存有效期, 比如7天, 是从"这个节点第一次拉取文件的时刻开始算的, 不是源站发布文件的时刻"
比如:
- 北京节点1月1日9点被用户触发, 拉取了v1包, 有效期到1月8日9点
- 上海节点1月2日14点被触发, 拉取v1包, 有效期到1月9日14点
- 源站1月7日把文件换成v2后, 北京、上海节点的缓存都没到期, 会继续存着v1包
csharp
复制代码
c.节点只会"被动更新", 不会主动检查源站
缓存没过期的节点, 会默认自己的库存是"最新的", 用户请求时直接返回本地旧包, 不会去源站确认"文件是不是换了"
只有两种情况节点会去源站拉取新文件
- 节点的缓存过期了, 用户请求时会先去源站校验, 发现文件更新就拉取v2
- 节点从来没缓存过这个文件(新节点/无用户访问过), 用户请求时直接去源站拉取最新的v2
csharp
复制代码
最终混杂的结果: "不同节点返回不同版本", 源站替换同名文件后, CDN的节点会分成三类
- ✅ 缓存未过期的节点: 继续返回旧包v1, 比如北京
- ❌ 缓存已过期的节点: 去源站拉取新包v2, 返回v2
- ❌ 无缓存的节点: 直接去源站拉取新包v2, 返回v2
用户访问CDN时, 会被自动分配到就近的节点:
- 被分配到北京节点的用户 -> 拿v1旧包
- 被分配到上海新节点的用户 -> 拿v2新包
从用户视角看, 就是"同一个下载地址, 有的人拿到旧包, 有的人拿到新包", 也就是"新旧包混在一起了"
csharp
复制代码
CDN的"混包"不是CDN主动将新旧包共存, 而是同名文件下, 各边缘节点的缓存过期时间不同、缓存状态不一致, 导致不同节
点返回不同版本的文件, 最终体现在用户侧的版本混乱; 只要给热更包加唯一标识(版本号/哈希), 让新旧包文件名不同,CDN
会将它们视为独立资源, 各节点的缓存互不影响, 就彻底不会有混杂问题了
2.解决方案
csharp
复制代码
解决"用户识别最新包"的关键是: 在CDN上放一个固定文件名的版本清单文件(比如version.json), 这个文件是"导航页", 它
本身文件名不变(但设置短缓存), 里面记录着最新热更包的"唯一标识文件名", "版本号", "CDN地址"等信息; Unity客户端
启动时, 先下载这个清单文件, 对比本地版本, 就能知道有没有新包、新包的CDN地址是什么, 然后下载对应的包
csharp
复制代码
a.先确定CDN上的文件结构, 这是避免缓存问题的基础
csharp
复制代码
b.版本清单文件(version.json)内容示例
这个文件是核心, 内容要包含足够的信息让客户端判断是否更新, 示例如下
csharp
复制代码
- 发布新包时, 只需要修改这个version.json里的内容, 比如把latestVersion改成1.0.1, packageName改成新包名, 然后
重新上传到CDN即可
- 给这个文件设置CDN缓存策略: Cache-Control: max-age = 60(缓存60秒), 确保客户端每次都能拿到最新的清单
csharp
复制代码
c.热更包的命名与缓存
- 热更包(Unity的AssetBundle包)命名必须带唯一标识(版本号/哈希值)
比如: hotupdate_v1.0.0.unity3d、hotupdate_v1.0.1.unity3d
- 给热更包设置CDN长缓存: Cache-Control: max-age=31536000(缓存1年), 因为文件名唯一, 不会和旧包混杂, 缓存越久
越省CDN资源