CDN - 思考如何能简化一点再一点

常用到CDN,之前使用中的问题是必须手动清理缓存,可以通过官方提供接口,根据网上一些脚本改造即可完成整体刷新。
手头的项目CDN使用了阿里的云存储OSS,每次资源更新,都需要手动上传CDN资源。看似不起眼的一些操作,按照当下了解的,大致文档从发布到上线CDN的操作路线是这样:
工作前情要稍微交代下:整个平台文档是多个仓库进行单独更新的。

  • 更新单一文档仓库(会作为父级仓库的子模块submodule)
  • 父仓库定期更新并执行编译,push代码到github(一键脚本,实现文档转json及mark2html功能)
  • 拖拽仓库文件至阿里提供的上传工具(只能实现逐一上传,因可能此存在发布缓慢问题)

根据反馈需求,主要花费集中在最后一步上,所以是时候想想办法:

  • githook?github提交后反馈信息执行某个cdn发布脚本

钩子功能github给予了使用说明,但想到构建工具应该均可实现这部分,于是假定了每次push代码,均会执行cdn发布脚本。思考问题主要集中在cdn发布脚本上:

  • 如何比较两次提交不同,目的是只对修改增加的文件做处理:存在问题是每次push,可能本地做了多次commit,不能简单的通过git diff HEAD HEAD^比较两次差别,因为存在遗漏的可能性太大。
  • 如何实现批量上传,官方提供的接口只支持单一文件上传;

如上问题2比较方便解决,问题集中到问题1:如何比较两次push不同,那就需要知道两次push的sha1记录。
技术上比较两次push不同,可通过git带参数命令实现:

git diff --name-status xxx xxx

获取最后分支记录信息,好说:

git rev-parse --revs-only HEAD

问题集中在上一次提交,如何?既然我们知道每次提交最新的结果,是否可以这样实现:

  • 将上一次更新的记录存储,当前脚本可以get
  • 当最新的push提交后,获取最新分支信息
    这样一个get请求,一个git命令即可将两者信息获取,使用diff比较获取数据后提取文件,执行发布cdn。
    问题原则上获得解决,不过仍存在两个问题:

  • 上一次保存记录在哪里?单独搞搞数据库?貌似有种杀猪用牛刀,于是沟通后,干脆将版本信息写到单独文件中存储发布在cdn上,这样一来可以存储,还能在cdn上查到目前最新的版本信息。但是小坑又来了,第一次添加到github仓库中做一次提交,原则上仓库不再更改,以后cdn上版本信息修改均交由cdn脚本执行修改提交,不单独做仓库提交。(即便仓库提交也无妨,毕竟发布cdn是由脚本控制,不是根据仓库更新来处理)

  • jetkins?具体使用需要再沟通

官方SDK上传文件

官方Node接口,提供单文件上传

var co = require('co');
var OSS = require('ali-oss')
var client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
  bucket: 'Your bucket name'
});
co(function* () {
  var result = yield client.put('object-key', 'local-file');
  console.log(result);
}).catch(function (err) {
  console.log(err);
});

aliyun-oss-bulk-upload

aliyun-oss-bulk-upload,一个批量上传的脚本,未测试:

  • 未使用OSS官方SDK,使用的是整合版
  • 读取所有文件夹及子目录进行上传,没有以上具体文件筛选要求实现

项目中其他坑及解决办法

co中map执行单一文件上传语法错误:

possible to yield Map object? ,通过co.wrap,再使用yield map即可正常执行

// upload
  // const task = co.wrap(function* (upfile) {
  //   var result = yield client.put(upfile, upfile);
  //   console.log(result);
  // })
  // yield fileList.map(task);

官方文档:
generator 转为普通function,返回promise,可以使用co.wrap,(执行yield map每一个异步需要返回一个promise,个人理解)

If you want to convert a co-generator-function into a regular function that returns a promise, you now use co.wrap(fn*).
其他链接

@2017-07-26 22:37