在架构设计上,一些容灾做的比较好的网站可能会采用多区域部署。
有的服务采用同一个云服务商的不同区域的服务。而有一些解决方案,在综合可用性,费用等实际情况考量下,可能会选用不同的云服务商。
在实际实践中,我就遇到了不同区域选用不同的云服务商的场景: 网站使用对象存储来管理。海外使用的云服务商是AWS, 中国区域使用的是阿里云。
两家云服务商分别有自己的对象存储服务,分别是:aws s3 与 阿里云OSS。
区域 |
云服务商 |
对象存储服务 |
中国区 |
阿里云 |
OSS |
海外区 |
亚马逊 |
S3 |

在代码实现上,我们往往需要同时引入aws跟aliyun 对象存储的sdk。
部署在海外的服务,上传文件到s3。部署在国内的服务,上传文件到阿里云oss。
所以,在服务里,往往需要同时引用双方的SDK,并针对性进行内容上传。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| const AWS = require('aws-sdk'); const OSS = require('ali-oss')
if (isOversea) { const s3 = new AWS.S3(); const params = { Bucket: bucket, Key: key, Body: file, }; s3.upload(params, (err, data) => { if (err) { return reject(new Error('upload failed!')); } return resolve(); }); } else { const client = new OSS({ "region": "oss-cn-hangzhou", "accessKeyId": "", "accessKeySecret": "", "bucket": "" })
client.put(key, file) .then(data => { return resolve() }).catch(ex => { console.log('err', ex) }) }
|
最近在做功能对接的时候,阅读阿里云官方文档,发现阿里云官方声明支持使用aws的sdk进行操作oss。
对象存储OSS提供了兼容Amazon S3的API。当您将数据从Amazon S3迁移到OSS后,只需简单的配置修改,即可让您的客户端应用轻松兼容OSS服务。本文主要介绍如何通过不同开发平台的S3 SDK完成初始化配置,然后使用S3 SDK接口访问OSS资源。
需要将上传的endpoint
进行调整即可,阿里云已经在数据层面对AWS的SDK进行了兼容。
代码同构
1 2 3 4 5 6 7 8 9 10
| const AWS = require('aws-sdk');
AWS.config.update({ accessKeyId: "OSS_AccessKeyId", secretAccessKey: "OSS_AccessKeySecret", region: "oss-cn-hangzhou", endpoint: 'https://oss-cn-hangzhou.aliyuncs.com', });
s3 = new AWS.S3({apiVersion: '2006-03-01'});
|
踩坑
使用此种代码同构的方式,在测试过程中出现了异常。
这个异常出现的场景:如果同一个应用,同时操作S3与OSS,就会出现操作对象存储失败。
原因则是因为,使用构建函数的配置update enpoint的方式, 会切换所有对象存储的endpoint
, 结果让数据要么统一到aws, 要么统一到阿里云
1 2 3 4 5 6
| AWS.config.update({ accessKeyId: "OSS_AccessKeyId", secretAccessKey: "OSS_AccessKeySecret", region: "oss-cn-hangzhou", endpoint: 'https://oss-cn-hangzhou.aliyuncs.com', });
|
优化
在AWS SDK的文档可以看到,S3的客户端支持实例化的方式,只需要在实例的时候,针对实例进行初始化配置即可。即使用工厂模式而非单例模式
重新调整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| const AWS = require('aws-sdk');
const initConfiguration = { apiVersion: '', accessKeyId: '', accessKeySecret: '', region: '', endpoint: '', };
this.client = new AWS.S3({ apiVersion: initConfiguration.apiVersion, accessKeyId: initConfiguration.accessKeyId, secretAccessKey: initConfiguration.accessKeySecret, region: initConfiguration.region, endpoint: initConfiguration.endpoint, });
|
如此一份兼容S3 与 OSS的 代码片段便大功告成了
横向对比可以发现,现在业界许多对象存储,除了阿里云OSS,腾讯云COS,同样都能使用 AWS 的SDK来操作他们的对象存储,因为他们都遵循AWS的 Simple Storage Service规范。
参考