hcnak.blog

posted at 2019-10-27 17:54:55 +0000

用CDN加速国内外亚马逊S3访问速度的问题

最近遇到个问题,因为之前文件都是储存在国外AWS账户上的。后面发现从国内访问国外S3是一件撞运气的事情。有些时候可以访问,有些时候连接被重置。

通过AWS SDK上传文件亦是如此。能否用得到的预签名链接上传成功完全碰运气。

这里主要两个问题,一个是上传到国外S3可能会失败。另外一个是国内访问国外S3可能不可达。

优化目标

对此我希望在程序改动尽量小的前提下加速国内访问国外S3与国外访问国内S3的速度。与此同时优化国内用户上传至S3的体验。

具体实现

文件上传

由于上传至S3是通过亚马逊SDK生成一个预签名链接,客户端根据该预签名链接在连接有效期内进行文件上传。所以,无论怎样客户端都需要能够直接访问该链接才能够完成上传。

优化上传做法无非有二:

方法一:增加一层代理,如在AWS 北京区部署一套HAProxy,走亚马逊的线路去访问国际服上的S3进行上传。

方法二:使用国内的对象存储提供商,当然这里选择AWS中国的S3储存。

对于方法一,几乎什么都不需要改,但实际使用中发现速度仍然不够理想,有时候会出现上传失败的情况。

方法二则需要在用户上传时,服务器根据用户地理位置选择相应的S3(AWS中国或AWS国际),生成对应的预签名上传链接给客户端。实际测试中还未遇到上传失败的情况。缺点是代码需要增加一层逻辑。

为了保证文件上传的成功率,此处选择了方法二。

具体策略为,根据用户调用接口时的地理位置,中国区域的用户统一上传至中国区的S3,其他区域的用户统一上传至国外S3。

至此,我们完成了上传至S3的优化。

文件下载

对于从S3下载文件,由于此处我们讲文件分开管理了,如果直接用代码逻辑实现区分,后期可能难以维护。所以希望对于下载文件尽量能够不修改服务器逻辑。

首先想到的就是CDN加速。在测试过程中还尝试了阿里和腾讯的CDN,有个奇怪的现象,在腾讯云的ECS服务器上测试阿里和腾讯的CDN对国外S3的访问速度。在已经缓存过的情况下,阿里云CDN每次都是0.0x秒,而腾讯CDN每次都是0.x秒。

不过为了集中管理云服务,选择使用了亚马逊的CloudFront。

也就是说我们用CloudFront来缓存国外和国内的S3(通过URL区分S3地域)。

因为是双向优化,所以选择在AWS中国区和AWS国际区分别部署一套CloudFront。然后每一个CloudFront都会AWS中国区的S3与AWS国际服的S3进行加速。

在CloudFront上通过访问的URL来区分是中国区AWS还是国际服AWS。

同时为了保证使用1个统一的链接访问两个CloudFront,我们需要在DNS上进行配置,将来自中国的的访客流量导向AWS中国区的CloudFront上,将其它区域的流量导向AWS国际服的CloudFront上。

最后,针对S3文件下载,架构设计如下:

CDN架构设计

参考



© kanchzl AT kanchz DOT com

last updated on 2022-07-27 01:57:54 +0000