最优化使用阿里OSS云存储

  上一篇文章讲到了为何要迁移到阿里OSS,经过几天时间的实际验证,发现还是踩了不少的坑,这里记录下,供参考。

  首先有几个先决条件如下:

  1. 全站所有请求必须HTTPS
  2. 全站仅允许出现自有二级域名
  3. 上行和下行流量均不经过ECS服务器

  (代码洁癖 8)

  阿里OSS我们可以简单的认为分两个部分:

一是存储有关的,提供了两个访问域名:一个是公网,一个内网

<bucket>.oss-cn-shenzhen.aliyuncs.com (A域名)
<bucket>.oss-cn-shenzhen-internal.aliyuncs.com (B域名)

二是为图像处理(缩图,转码)有关的,也提供了一个访问域名:

<bucket>.img-cn-shenzhen.aliyuncs.com (C域名)

我们在这个图像处理的功能上面绑定了一个自有的二级域名:

image.snapast.com (D域名)

默认分配并指向了下面的CDN加速节点域名:

image.snapast.com.w.kunlunca.com (E域名)

  暂且称为A~E域名,注意其中细微差别。其中A和B域名本身是支持HTTPS的,但C不行,在绑定了D之后,可以上传SSL证书开启。A域名也可以绑定自有域名,但不支持HTTPS。图像处理设置了禁止原图访问,也就是C,D域名仅允许通过“样式”访问到缩略图。但A,B不受限制,本来就不同的系统。

于是第一个方案是这样的:

用户上传:HTTPS POST A域名
用户访问:HTTPS GET D域名

  初看没啥问题,除了引入一个第三方域名,不符合预定规范,但也运行良好,但有个很严重的问题,会泄漏原图,将D域名的路径拼接到A上面就能拿到原图。故pass掉,和客服聊了后给了个鸡贼的方案:

方案二:

用户上传:HTTPS POST upload.snapast.com -> proxy_pass -> B域名
用户访问:HTTPS GET D域名

  在nginx上将用户上行的POST请求转发到B域名,这样可以在nginx层面拦截原图访问,并可以支持自有域名HTTPS。虽然又点不符合规范了,虽然ECS下行带宽还是蛮大的,proxy_pass也是内网地址,似乎也无大碍。

方案三:
将bucket设置为私有,这样POST不变,GET需要增加signature,想想就复杂,搞的URL又长又丑,没再尝试。

  后来想想,能不能直接POST到D域名试试,居然成功了。Object 管理中证实了文件是传成功的,但感觉怪怪的,原来CDN还能upload。官方文档似乎也没有说这样用合不合理,暂且先如此把。

使用阿里云OSS WEB直传

  最近在忙着将snapast.com的图片迁移到阿里OSS服务器上,并采用WEB直传方案,以加快客户端上传速度。并使用CDN访问方式来提高图片加载速度。目前所有的图片都是存储在ECS云服务器上,用的是FastDFS存储,纯Java的图片缩放处理,速度比较慢。并且单线程就将CPU消耗完了,2M的带宽也经不起并发访问,于是决定将图片迁移到OSS上。

  WEB直传的架构设计还是很优秀的,客户端直接POST请求到OSS服务器,无需经过ECS服务器,ECS只是计算一个Policy,并接收OSS回调,整个图片上传流程就完成了。OSS具有阿里的海量CDN支持,各种网络下都能很好的优化。

这里主要记录下一些细节:

  1. OSS要设置Cors规则,以便跨域请求
  2. 2. Bucket区域要和ECS区域一致,方便内网拉取数据
  3. 使用uploadifive上传组件且auto设置为true时,在onAddQueueItem方法中获取Policy,已换plupload,在BeforeUpload中获取Policy。
  4. 由于OSS会忽略请求中文件域以后的字段,因此在封装参数的时候,将文件域(Content-Disposition: form-data; name=”file”; filename=”xxx.jpg”)置于最后,这货貌似完全照搬Amazon S3,否则会找不到key

  Upload差不多就这样了,先写到这。