Scratch CDN镜像笔记
文章目录
前言
2019.11.23 CodeLab在国家图书馆做了个活动,接下来会陆续开展活动,随着用户的加入,为了方便大家的交流,CodeLab的编程社区正提上日程。
我们希望构建类似scratch.mit.edu的社区。所以复用了Scratch开放的前端项目:scratch-www, 并构建了与之兼容的后端(参考Scratch3.0技术分析之后端API(第0篇))。
Scratch全球社区有海量(1亿+)优秀项目, 我们希望国内用户能方便地访问它。于是为Scratch做了CDN。
本文对CDN镜像实施时遇到的问题过个笔记。
ps: 这个思路是通用的,也是做笔记的原因。
思路
使用七牛的镜像机制来做CDN。
问题笔记
静态资源
音乐加载
Scratch将它自身的静态资源放在CDN上,诸如:
- 角色图片
- 背景图片
- 音乐
角色图片 和 背景图片 会一次加载所有内容,所以打开一次,便会触发所有资源的CDN镜像机制。
音乐则不然,属于lazy load,需要逐个点击/悬停才加载,这带来了一个问题: 许多资源在第一次使用时,要等待镜像的完成,十分缓慢。
思路
有许多种解决方案,我想到3种:
- 修改scratch静态资源的加载机制,不使用CDN,直接从自己的服务器拉取静态资源。
- 与第一种方法类似,将静态资源放在自己的服务器上,但使用CDN镜像它。
- 镜像官方静态资源,使用自动化机制逐个镜像静态资源
为了兼容Scratch和考虑后期的升级,我决定采用第三种方案.
思路很简单: 使用正则表达式找出所有资源的标识(形如5cb46ddd903fc2c9976ff881df9273c9.wav
), 写一个脚本逐个请求。
动手
思路清楚之后,很容易执行。
我们在build好的代码里,寻找音乐资源的标识(形如5cb46ddd903fc2c9976ff881df9273c9.wav
)。
其实音乐资源在开发源码中更好找,我之所以在build之后的代码里找,是为了长期的兼容性,md5标识可能会改变。
简单搜索一下,可以发现数据都在lib.min.js
文件里。
正则表达式
使用正则表达式找到它:
ack -ho '(?<=md5:")[a-z\d]+?.wav(?=")' lib.min.js
前边这个正则表达式,有2处可能不好理解: (?<=md5:")
和 (?=")
, 在正则中叫前瞻和后顾,实际上是把目标字符串的上下文信息加入进来,我们的目标字符串(md5:"5cb46ddd903fc2c9976ff881df9273c9.wav"
)以md5:"
开头,以"
结尾.
如果你觉得这个不好读,可以使用以下更易读的版本,当然也更啰嗦些:
ack -ho 'md5:"[a-z\d]+?.wav"' lib.min.js | ack -ho '[a-z\d]+?.wav'
一共找到792项,我们将其存到文件里
ack -ho '(?<=md5:")[a-z\d]+?.wav(?=")' lib.min.js > /tmp/music_list.txt
之后使用Python来触发对这些静态资源的镜像。
Python脚本
Python脚本的职责是,构建出音乐资源镜像地址,对其访问(HTTP OPTION/GET), 镜像地址形如:https://cdn.assets.scratch.mit.edu/internalapi/asset/5cb46ddd903fc2c9976ff881df9273c9.wav/get/
cdn.assets.scratch.mit.edu
替换为镜像仓库的域名。
使用循环依次将5cb46ddd903fc2c9976ff881df9273c9.wav
替换为/tmp/music_list.txt
中的文件标识即可。
之后使用aiohttp client去并发请求这些资源,
当然你也可以使用任何自己喜欢的语言和http库,httpie和curl都很方便。注意设置超时时间,镜像可能需要时间,我们不必拿到请求结果,只需触发请求即可。
至此,完成上述工作。
文章作者 种瓜
上次更新 2019-12-02