FC 多云对象存储数据容灾

流程

为什么采用 S3 呢? 基本国内大型的云服务商都对 AWS S3 API 进行了兼容,采用 S3 也比较方便我们的处理,不需要去安装每个云服务商提供的 SDK,然后根据他们的 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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php

require 'vendor/autoload.php';

use OSS\OssClient;
use OSS\Core\OssException;
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
use Aws\S3\MultipartUploader;
use Aws\Exception\MultipartUploadException;

$config = [
'huawei' => [
'credentials' => [
'key' => '3R9RMYDLWTSWUTL8SZ0C', // Secret ID
'secret' => 'iEgSGsHongfsxJjXFS4X5ixxPxR6TSeBxYYlfPNC', // Secret Key
],
'bucket' => 'hongfs-backup-wc0dl2nipqz68tjr', // 存储桶名称
'endpoint' => 'https://obs.cn-south-1.myhuaweicloud.com', // Endpoint
'region' => 'cn-south-1', // 地域
'version' => '2006-03-01', // 版本号,固定
],
'tencent' => [
'credentials' => [
'key' => 'xx',
'secret' => 'xx',
],
'bucket' => 'hongfs-backup-xx-1252156936',
'endpoint' => 'https://cos.ap-guangzhou.myqcloud.com',
'region' => 'ap-guangzhou',
'version' => '2006-03-01',
],
];

function handler($event, $context) {
global $config;

// 获取事件信息
$event = json_decode($event, true)['events'][0];

// 实例化 OSS
$oss = new OssClient(
$context['credentials']['accessKeyId'],
$context['credentials']['accessKeySecret'],
'https://oss-' . $event['region'] . '-internal.aliyuncs.com',
false,
$context['credentials']['securityToken']
);

// 上传的文件 key (目录/文件名.后缀)
$object_key = $event['oss']['object']['key'];

// 本地临时存储路径
$filepath = '/tmp/' . $context['requestId'] . '-' . basename($object_key);

try {
// 下载文件到临时存储
$oss->getObject($event['oss']['bucket']['name'], $object_key, [
OssClient::OSS_FILE_DOWNLOAD => $filepath,
]);
} catch (OssException $e) {
echo $e->getMessage() . "\n";
return '0';
}

// 循环厂商
foreach($config as $item) {
// 将本地文件采用切片方式上传到对应厂商
$uploader = new MultipartUploader(new S3Client($item), $filepath, [
'bucket' => $item['bucket'],
'key' => $object_key,
]);

try {
// 执行上传操作
$uploader->upload();
} catch (MultipartUploadException $e) {
echo $e->getMessage() . "\n";
}
}

// 删除本地文件释放空间
unset($filepath);

return '1';
}

部署

OSS

  1. 创建一个存储桶

FC

  1. 创建一个函数,函数的地域和存储桶的地域一致,语言为 PHP,内存 128 MB,超时时间 600 秒。
  2. 配置服务页面添加 AliyunOSSFullAccess 权限。
  3. 在刚刚创建的函数页面上传代码,代码压缩包在文章底部。
  4. 将代码里面的配置换成自己的。
  5. 设置一个 OSS 触发器,事件源为刚刚创建的存储桶,触发事件为 oss:ObjectCreated:PutObject oss:ObjectCreated:CompleteMultipartUpload (这两个是上传会涉及到的事件,不处理其他修改或者删除等),触发规则可以根据自己需求,最后还需要授权下 AliyunOSSEventNotificationRolePolicy 权限。

测试

阿里云

华为云

腾讯云


源码下载

往上