OSS工作原理
數據以對象(Object)的形式存儲在OSS的存儲空間(Bucket )中。如果要使用OSS存儲數據,您需要先創建Bucket,並指定Bucket的地域、訪問權限、存儲類型等屬性。創建Bucket後,您可以將數據以Object的形式上傳到Bucket,並指定Object的文件名(Key)作爲其唯一標識。
當前使用Go接入: aliyun/aliyun-oss-go-sdk: Aliyun OSS SDK for Go (github.com)
服務端使用流程:服務端簽名直傳並設置上傳回調概述 (aliyun.com)
縮略圖使用教程:圖片縮放 (aliyun.com)
視頻截圖使用教程:視頻截幀 (aliyun.com)
Web端上傳介紹
市面常見方案
和數據直傳到OSS相比,以上方法存在以下缺點:
- 上傳慢:用戶數據需先上傳到應用服務器,之後再上傳到OSS,網絡傳輸時間比直傳到OSS多一倍。如果用戶數據不通過應用服務器中轉,而是直傳到OSS,速度將大大提升。而且OSS採用BGP帶寬,能保證各地各運營商之間的傳輸速度。
- 擴展性差:如果後續用戶數量逐漸增加,則應用服務器會成爲瓶頸。
- 費用高:需要準備多臺應用服務器。由於OSS上行流量是免費的,如果數據直傳到OSS,將節省多臺應用服務器的費用。
服務端簽名直傳並設置上傳回調
客戶端直傳方案
返回結果:
{
"accessid":"LTAI5tAzivUnv4ZF1azP****",
"host":"[http://post-test.oss-cn-hangzhou.aliyuncs.com](http://post-test.oss-cn-hangzhou.aliyuncs.com/)",
"policy":"eyJleHBpcmF0aW9uIjoiMjAxNS0xMS0wNVQyMDoyMzoyM1oiLCJjxb25kaXRpb25zIjpbWyJjcb25XC8i****",
"signature":"I2u57FWjTKqX/AE6doIdyff1****",
"expire":1446727949,
"callback":"eyJjYWxsYmFja1VybCI6Imh0dHA6Ly9vc3MtZGVtby5hbGl5dW5jcy5jb206MjM0NTAiLAoiY2FsbGJhY2tCb2R5" // base 64
"dir":"user-dirs/"
}
base64 解析如下
callbackUrl | OSS向服務器發送的URL請求。 |
---|---|
callbackHost | OSS發送該請求時,請求頭部所帶的Host頭。 |
callbackBody | OSS發送給應用服務器的內容。如果是文件,可以是文件的名稱、大小、類型等。如果是圖片,可以是圖片的高度、寬度等。 |
callbackBodyType | 請求發送的Content-Type。 |
{
"callbackUrl":"[http://oss-demo.aliyuncs.com:23450](http://oss-demo.aliyuncs.com:23450/)",
"callbackBody":"filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}",
"callbackBodyType":"application/x-www-form-urlencoded"
}
創建Bucket
client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
if err != nil {
// HandleError(err)
}
err = client.CreateBucket("my-bucket")
if err != nil {
// HandleError(err)
}
注意事項:
- 一旦創建,則無法更改其名稱。
- Bucket名稱必須全局唯一。
- 只能包括小寫字母、數字和短劃線(-)。
- 必須以小寫字母或者數字開頭和結尾。
- 長度必須在3~63字符之間。
上傳文件
client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
if err != nil {
// HandleError(err)
}
bucket, err := client.Bucket("my-bucket")
if err != nil {
// HandleError(err)
}
err = bucket.PutObjectFromFile("my-object", "LocalFile")
if err != nil {
// HandleError(err)
}
下載文件:
client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
if err != nil {
// HandleError(err)
}
bucket, err := client.Bucket("my-bucket")
if err != nil {
// HandleError(err)
}
err = bucket.GetObjectToFile("my-object", "LocalFile")
if err != nil {
// HandleError(err)
}
數據存儲表
CREATE TABLE IF NOT EXISTS `mydb`.`storage` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(256) NOT NULL COMMENT '文件名稱',
`path` VARCHAR(256) NOT NULL COMMENT 'OOS 路徑',
`ext` VARCHAR(32) NOT NULL DEFAULT 0 COMMENT '拓展名稱',
`md5` VARCHAR(32) NOT NULL COMMENT '資源的MD5 ',
`creator_id` INT(16) NOT NULL DEFAULT 0 COMMENT '創建人id',
`created_at` INT(10) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
INDEX `md5` (`md5` ASC) VISIBLE)
ENGINE = InnoDB
問題記錄
- 使用服務端簽名直傳上傳回調的方式,同一資源上傳,是否可以去重?
OSS 沒有去重的功能,只有重名上傳禁止覆蓋的功能 - 應用服務器回調失敗後,是否重新發送,間隔時間是什麼?
出於安全考慮,OSS的回調請求只會等待5秒。如果5秒後還沒有返回,那麼OSS就會主動斷開與應用服務器的連接,並返回給客戶端超時錯誤