Unity小游戏CDN部署方案
Tags: 小游戏, 架构, 游戏开发
💡 前言:最近做了一个Unity手游转小游戏,本文主要记录一下我们小游戏的CDN部署策略,以及正式环境和策划环境隔离的设计
总体设计
- 所有文件平铺展开到CDN资源目录
- 每个文件带上类似md5文件内容前面的部分,不通版本的文件md5标识必然不同
- 游戏启动时候,询问版本服务器当前包的版本信息
- 加载文件时候带上版本后缀,实现版本隔离
- 手机连接特定wifi(出口IP不同),服务器将请求转发到测试版本服务器,可以让改手机提前体验到测试版本内容。实现测试版本和正式版本切换
- 每个文件都是固定URL,不会有随机数部分,对本地缓存是非常友好的
这样设计的好处是在于,我们不需要每次发布新版本都切换CDN资源目录,玩家只需要下载版本差异的文件,体验上更好,也更节省玩家流量
上面是总体的设计思想,下面将展开讲一下我们是怎么做的
一、AB打包改造
我们都知道Unity打包AB时候提供了一个BuildAssetBundleOptions.AppendHashToAssetBundleName
模式,会在每个ab包上附加上hash签名,类型ab_32hash.ab
。我们也考虑过这个,但觉得这个太长了,决定优化一下,采用crc32生成8位的文件签名。在StreamAssets的描述文件中记录此签名信息,我们的描述ab的StreamAssets.xml格式类似如下:
<xml>
<bundles>
<bundle>
<bundleName>ab.ab</bundleName>
<fileHash>crc32签名</fileHash>
......
<bundle>
</bundles>
</xml>
最终放在cdn中的ab的文件名格式是:
👉 md5(原始ab包文件名)_crc32签名
记录各个ab以及依赖的文件名是StreamingAssets.xml_crc32签名
- 游戏启动时候,远程先加载对应版本的
StreamingAssets.xml
,将每个ab包以及hash签名载入到内种 - 加载资源时候,先找到资源所在的ab包,通过记录的ab包的签名生成最终路径,然后从远程加载
通过上述ab打包的改造,打出的ab包就可以直接在CDN目录解压了,不用担心不同版本同一个ab包会产生覆盖的情况。
二、Lua代码打包改造
在App模式下,我们的Lua代码是按需加载,用到哪个代码就直接从本地磁盘加载。由于Lua代码文件巨多,小游戏模式下如果每个Lua文件都需要走网络加载,必然导致不太流畅。所以我们采取的发难是,Lua所有代码打包成一个zip包,系统启动时候下载对应版本的Lua代码zip包,在内存中解压,后续代码查找都直接在内存中查找。
同理我们Lua代码的命名固定是lua.zip_crc32签名
三、版本信息哪里来?
上述文件的改造方案,通过介绍实现起来都比较简单。但有一个问题,我们游戏启动时候怎么知道加载那个版本的(crc签名)的StreamingAssets.xml
和lua.zip
。这部分信息不能内置到游戏首包内,如果那样的话就无法做到热更了。我们的方案是引入一个版本管理服务。
先看看发布流程
发布版本时候在版本服务器记录最新版本信息
游戏启动时候,会请求版本服务器API,版本服务器根据包的信息查找记录,返回版本信息。我们的返回信息格式一般如下:
state,cdnUrl,版本信息
然后去cdn加载对应Lua代码
和StreamingAssets.xml
。这样就完成了版本管理
我们发现有一个版本服务器有很多好处:
- 可以实现不同包的版本管理,根据不同的包返回不同的版本信息
- 测试环境和正式环境的切换。测试环境返回的版本信息可以是最新的发布,待线上真实验证后再同步到正式环境
- 快速版本回滚
以上就是我们Unity小游戏的CDN资源管理方案!