关于阿里云oss:golang使用阿里云OSS对象存储

17次阅读

共计 14670 个字符,预计需要花费 37 分钟才能阅读完成。

概念

  • Bucket存储空间
  • Object文件
  • ObjectKey文件名 ,文件的惟一标识,与KeyObjectName 为同一概念
  • Region地区,OSS 数据中心的地理位置
  • Endpoint域名
  • AccessKey密钥 ,由AccessKey IDAccessKey Secret组成

计费

总费用 = 存储费 + 长期存储费 + 数据取回费 + 流量费 + 申请费 + 其他费用

一、存储费

存储费 = 文件大小(GB) x 单价 ÷ 30 ÷ 24 x 存储时长(hour)

存储类型 单价
规范 - 本地冗余 0.12
规范 - 同城冗余 0.15
低频拜访 - 本地冗余 0.08
低频拜访 - 同城冗余 0.10
归档 0.033
冷归档 0.015

最贵 的规范存储的单价是 最便宜 的冷归档存储的 8 倍。
存储一个大小为 1G 的文件每月须要领取 0.12 元的存储费。

二、长期存储费

长期存储费 = 文件大小(GB) x 单价 ÷ 30 ÷ 24 x 冻结时长(hour)

存储类型 单价
冷归档 0.12

冷归档文件在冻结期间,须额定领取一笔依照规范存储单价计算的长期存储费用。

三、数据取回费

数据取回费 = 文件大小(GB) x 单价

存储类型 单价
规范 0
低频拜访 0.0325
归档 0.06
冷归档 0.03~0.2

四、流量费

流量费 = 流量(GB) x 单价

流量方向 单价
上传 0
内网下载 0
外网下载(0-8) 0.25
外网下载(8-24) 0.50
CDN 回源下载 0.15
跨区域复制(中国大陆) 0.50
外网下载(0-8) 0.25

上传收费,下载免费。
一个大小为 1G 的文件,每下次 1 次,须要领取 0.25 元的流量费。

五、申请费

申请费 = math.Ceil(申请次数 /10000) x 单价

申请类型 规范 低频拜访 归档 冷归档
PUT 0.01 0.1 0.1 0.1
GET 0.01 0.1 0.1 0.1
取回 / / / 0.3 ~ 30

冷归档文件的取回申请每一万次需领取 30 元的申请费。

六、其他费用

跨区域文件复制流量费、图片处理费、图片压缩费、视频截帧费、标签费、传输减速费、DDoS 防护费、元数据管理费、敏感数据保护费等等。

存储类型

规范 + 低频 + 归档 + 冷归档

比照指标 规范 低频 归档 冷归档
最小计量单位 0 64KB 64KB 64KB
最小存储时长 0 30 天 60 天 180 天
拜访提早 0 0 1min 1-12hour
数据取回费用 0 30 天 60 天 180 天

URL

公共:<Schema>://<Bucket>.<Endpoint>/<Object>
公有:<Schema>://<Bucket>.<Endpoint>/<Object>? 签名信息

Bucket

CRUD

Bucket创立后不反对批改,所以只有CRD,没有U

package main

import (
    "fmt"
    "os"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    // 创立 OSSClient 实例。// yourEndpoint 填写 Bucket 对应的 Endpoint。// 以华东 1(杭州)为例,填写为 https://oss-cn-hangzhou.aliyuncs.com。client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret",)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 新增
    err = client.CreateBucket(
        "examplebucket", 
        oss.StorageClass(oss.StorageIA), 
        oss.ACL(oss.ACLPublicRead),
        oss.RedundancyType(oss.RedundancyZRS)
    )
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }
    /* 
    StorageClass:存储类型。StorageStandard= 规范存储
        StorageIA= 低频拜访
        StorageArchive= 归档存储
        StorageColdArchive= 冷归档存储
    ACL:拜访权限。ACLPrivate= 公有
        ACLPublicRead= 公共读
        ACLPublicReadWrite= 公共读写
    RedundancyType:冗余类型。RedundancyLRS= 本地冗余
        RedundancyZRS= 同城冗余
    */

    // 查问
    marker := ""
    for {lsRes, err := client.ListBuckets(oss.Marker(marker))
        if err != nil {fmt.Println("Error:", err)
            os.Exit(-1)
        }

        // 默认状况下一次返回 100 条记录。for _, bucket := range lsRes.Buckets {fmt.Println("Bucket:", bucket.Name)
        }

        if lsRes.IsTruncated {marker = lsRes.NextMarker} else {break}
    }

    // 查问 Region ID
    regionID, err := client.GetBucketLocation("examplebucket")
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }
    fmt.Println("Bucket Location:", regionID) // oss-cn-shanghai
    /*
        Region ID 能够了解为 Endpoint 的前缀:外网 Endpoint:oss-cn-shanghai.aliyuncs.com
        内网 Endpoint:oss-cn-shanghai-internal.aliyuncs.com
    */

    // 删除
    err = client.DeleteBucket("examplebucket")
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }
}

生命周期

通过设置生命周期,能够实现定期将 Bucket 内的 Object 转换存储类型,或者将过期的 Object 和碎片文件删除,进而升高存储费用。

能够基于 最初一次批改工夫 (Last Modified Time)或 最初一次拜访工夫(Last Access Time)创立生命周期规定。

限度 最初一次批改工夫 最初一次拜访工夫
实用场景 拜访模型确定 拜访模型不确定
是否反对删除 Object 反对 不反对
存储类型的转换是否可逆 不可逆 可逆

基于最初一次批改工夫

最初一次批改工夫,其实根本能够了解为创立工夫。

这样就能够实现相似「上传 N 天后删除」或者「上传 N 天后将存储类型由规范切换为低频拜访」的需要。

一些限度
  1. 仅反对依据 前缀 标签 进行匹配,不反对通配符匹配、后缀匹配以及正则匹配。
  2. 能够叠加,但下限为 1000 条。
  3. 溯及既往
  4. 失效:规定创立胜利后的 24 小时内实现加载,加载胜利后将于每天的 08:00 执行。
  5. 最初批改工夫与规定执行工夫的 距离 必须大于 24 小时。
package main

import (
    "fmt"
    "os"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func Main() {
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret",)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 定义规定

    // 前缀为 10086 的 Object 将于最初一次批改工夫后的第 14 天删除
    ruleA := oss.BuildLifecycleRuleByDays("ruleA", "10086", true, 14)

    // 前缀为 10010 的 Object 将于 2025 年 10 月 10 日的 08:00 删除
    ruleB := oss.BuildLifecycleRuleByDate("ruleB", "10010", true, 2025, 10, 10)

    // 前缀为 10000 的 Object 的存储类型将于最初一次批改工夫的 30 天后变更为低频拜访
    ruleC := oss.LifecycleRule{
        ID:     "ruleC",
        Prefix: "10000",
        Status: "Enabled",
        Transitions: []oss.LifecycleTransition{
            {
                Days:         30,
                StorageClass: oss.StorageIA,
            },
        },
    }

    // 设置规定
    err = client.SetBucketLifecycle("examplebucket", []oss.LifecycleRule{ruleA, ruleB, ruleC},
    )
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }
}

基于最初一次拜访工夫

基于最初一次拜访工夫的生命周期规定仿佛不反对SDK

Object

类型

Object依据上传形式能够分为以下三类:

上传形式 类型
简略上传 Normal
分片上传 Multipart
追加上传 Appendable

命名

  • UTF-8编码
  • 1 ~ 1024个字符
  • 不能以 /\结尾

上传和删除

package main

import (
    "fmt"
    "os"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func Main() {
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret",)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 生成 Bucket 实例
    bucket, e := client.Bucket("examplebucket")
    if err != nil {fmt.Println("Error:", e)
        os.Exit(-1)
    }

    // 上传
    if err = bucket.PutObject("objectKey", file); err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 删除
    if err = bucket.DeleteObject("objectKey"); err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }
}

访问控制

阿里云提供四种类型的拜访权限控制策略:

类型 束缚对象
RAM Policy OSS 服务所属阿里云主账号的 RAM
Bucket Policy 所有阿里云主账号的 RAM 和匿名用户
Bucket ACL Bucket
Object ACL Object

RAM Policy

RAM Policy 为 JSON 格局,其构造为:

{
  "Version": "1",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": ["oss:PutObject"],
      "Resource": ["acs:oss:*:*:examplebucket"],
      "Condition": {}}
  ]
}

Version:版本
Statement:受权语句
Effect:效劳(Allow / Deny)
Action:操作
Resource:资源
Condition:条件

能够应用官网的 RAM 策略编辑器疾速生成 RAM 策略。

【示例】禁止指定 RAM 上传 Object 到 Bucket。

step1:生成RAM Policy
{
  "Version": "1",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": ["oss:PutObject"],
      "Resource": ["acs:oss:*:*:avatar"],
      "Condition": {}}
  ]
}
step2:增加权限策略:

控制台 – RAM 访问控制 – 权限治理 – 创立权限策略 – 脚本编辑

step3:为 RAM 增加权限策略:

控制台 – RAM 访问控制 – 身份治理 – 用户 – 增加权限

Bucket Policy

package main

import (
    "fmt"
    "os"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func Main() {
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret",)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 配置 policy(禁止 192.168.1.1 之外的所有人对 examplebucket 的所有申请)policy := `{
        "Version": "1",
        "Statement": [
            {"Principal": ["*"],
                "Effect": "Deny",
                "Action": ["oss:*"],
                "Resource": ["acs:oss:*:*:examplebucket"],
                "Condition": {
                    "NotIpAddress": {"acs:SourceIp": ["192.168.1.1"]
                    }
                }
            }
        ]
    }`

    // 设置
    err = client.SetBucketPolicy("examplebucket", policy)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 查问
    policy, e := client.GetBucketPolicy("examplebucket")
    if e != nil {fmt.Println("Error:", e)
        os.Exit(-1)
    }

    // 删除
    err = client.DeleteBucketPolicy("examplebucket")
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }
}

Bucket ACL

package main

import (
    "fmt"
    "os"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func Main() {
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret",)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 设置 examplebucket 的权限为公共读
    err = client.SetBucketACL("examplebucket", oss.ACLPublicRead)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 设置 examplebucket 的权限为公共读写
    err = client.SetBucketACL("examplebucket", oss.ACLPublicReadWrite)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 设置 examplebucket 的权限为公有
    err = client.SetBucketACL("examplebucket", oss.ACLPrivate)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 查问 Bucket ACL
    res, e := client.GetBucketACL("examplebucket")
    if e != nil {fmt.Println("Error:", e)
        os.Exit(-1)
    }
}

Object ACL

package main

import (
    "fmt"
    "os"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func Main() {
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret",)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 生成 Bucket 实例
    bucket, e := client.Bucket("examplebucket")
    if e != nil {fmt.Println("Error:", e)
        os.Exit(-1)
    }

    // 设置 exampleobject 的权限为公共读
    err = bucket.SetObjectACL("exampleobject", oss.ACLPublicRead)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 设置 exampleobject 的权限为公共读写
    err = bucket.SetObjectACL("exampleobject", oss.ACLPublicReadWrite)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 设置 exampleobject 的权限为公有
    err = bucket.SetObjectACL("exampleobject", oss.ACLPrivate)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 设置 exampleobject 的权限为继承 Bucket
    err = bucket.SetObjectACL("exampleobject", oss.ACLDefault)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 查问 Object ACL
    res, er := bucket.GetObjectACL("exampleobject")
    if er != nil {fmt.Println("Error:", er)
        os.Exit(-1)
    }
}

数据容灾

同城冗余

如果把默认的本地冗余比喻为一份数据存在同一机房内的三个不同硬盘中的话,那么同城冗余就是将数据存在同一数据中心的三个不同机房。

从本地冗余到同城冗余,隔离等级由 硬盘级 回升到 机房级

err = client.CreateBucket(
    "examplebucket", 
    oss.StorageClass(oss.StorageIA), 
    oss.ACL(oss.ACLPublicRead),
    oss.RedundancyType(oss.RedundancyZRS)
)
/* 
    RedundancyType:冗余类型。RedundancyLRS= 本地冗余
    RedundancyZRS= 同城冗余
*/

冗余类型仅反对创立 Bucket 时指定,一旦创立不反对批改。

跨城冗余

跨城冗余就是将数据寄存在不同城市的机房。

从同城冗余到跨城冗余,隔离等级由 机房级 回升到 城市级

package main

import (
    "fmt"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
    "os"
)

func main()  {
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret",)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    /* 
    指定仅同步复制规定创立后新写入的数据
    不同步源 Bucket 的历史数据
    且尔后将源 Bucket 执行的所有操作都将实时同步到指标 Bucket
    */
    putXml := `<?xml version="1.0" encoding="UTF-8"?>
    <ReplicationConfiguration>
      <Rule>
        <PrefixSet>
            <! -- 指定待复制 Object 的前缀 prefix_1 和 prefix_2。指定 Prefix 后,只有匹配该 Prefix 的 Object 才会复制到指标 Bucket。-->
            <! -- 如果您须要将源 Bucket 中的所有 Object 复制到指标 Bucket,则无需设置 Prefix。<Prefix>prefix_1</Prefix>
            <Prefix>prefix_2</Prefix>
        </PrefixSet>
        <! -- 指定能够被复制到指标 Bucket 的操作。默认值为 ALL,示意源 Bucket 的所有操作都会复制到指标 Bucket。-->
        <Action>ALL</Action>
        <Destination>
            <! -- 指定数据要复制到的指标 Bucket。-->
            <Bucket>destexamplebucket</Bucket>
            <! -- 指定指标 Bucket 所在的 Region。-->
            <Location>oss-cn-beijing</Location>
            <! -- 指定数据复制时应用的数据传输链路。此处设置为 oss_acc,示意应用了传输减速链路。-->
            <TransferType>oss_acc</TransferType>
        </Destination>
        <! -- 默认同步历史数据。此处设置为 disabled,示意禁止同步历史数据。-->
        <HistoricalObjectReplication>disabled</HistoricalObjectReplication>
        <! -- 指定受权 OSS 进行数据复制的角色名称。如果指定应用 SSE-KMS 加密指标对象,则必须指定该元素。-->
        <SyncRole>aliyunramrole</SyncRole>
        <SourceSelectionCriteria>
          <SseKmsEncryptedObjects>
            <! -- 指定 OSS 是否复制通过 SSE-KMS 加密创立的对象。-->
            <Status>Enabled</Status>
          </SseKmsEncryptedObjects>
        </SourceSelectionCriteria>
        <EncryptionConfiguration>
            <! -- 指定 SSE-KMS 密钥 ID。如果指定 Status 为 Enabled,则必须指定该元素。-->
           <ReplicaKmsKeyID>c4d49f85-ee30-426b-a5ed-95e9139d****</ReplicaKmsKeyID>
       </EncryptionConfiguration>
     </Rule>
   </ReplicationConfiguration>`

    // 开启跨区域复制
    err = client.PutBucketReplication("srcexamplebucket",putXml)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }
}            

数据加密

OSS 服务侧加密

上传 Object 时,OSS对收到的文件进行加密,再将加密文件长久化保留。

下载 Object 时,OSS主动将加密文件解密后返回,并在响应头中返回 x-oss-server-side-encryption,用于申明该文件进行了OSS 服务侧加密。

package main

import (
    "fmt"
    "os"

    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    // 创立 OSSClient 实例
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret",)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 初始化加密规定,应用 AES256 算法
    config := oss.ServerEncryptionRule{SSEDefault: oss.SSEDefaultRule{SSEAlgorithm: "AES256"},
    }

    // 设置 OSS 服务侧加密
    err = client.SetBucketEncryption("examplebucket", config)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }
}

应用服务侧加密

应用服务侧加密是指将 Object 发送到 OSS 之前进行加密,而后将加密后的 Object 传输至 OSS 长久化保留。

package main

import (
    "bytes"
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "os"

    "github.com/aliyun/aliyun-oss-go-sdk/oss"
    "github.com/aliyun/aliyun-oss-go-sdk/oss/crypto"
)

func main() {
    // 创立 OSSClient 实例。client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>",)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 创立一个主密钥的形容信息,创立后不容许批改。主密钥形容信息和主密钥一一对应。// 如果所有的 Object 都应用雷同的主密钥,主密钥形容信息能够为空,但后续不反对更换主密钥。// 如果主密钥形容信息为空,解密时无奈判断应用的是哪个主密钥。// 强烈建议为每个主密钥都配置主密钥形容信息(json 字符串), 由客户端保留主密钥和形容信息之间的对应关系(服务端不保留两者之间的对应关系)。// 由主密钥形容信息 (json 字符串) 转换的 map。materialDesc := make(map[string]string)
    materialDesc["desc"] = "<your master encrypt key material describe information>"

    // 依据主密钥形容信息创立一个主密钥对象。masterRsaCipher, err := osscrypto.CreateMasterRsa(materialDesc, "<your rsa public key>", "<your rsa private key>",)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 依据主密钥对象创立一个用于加密的接口, 应用 aes ctr 模式加密。contentProvider := osscrypto.CreateAesCtrCipher(masterRsaCipher)

    // 获取 bucket。cryptoBucket, err := osscrypto.GetCryptoBucket(client, "<yourBucketName>", contentProvider)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 上传时时主动加密。err = cryptoBucket.PutObject("<yourObjectName>", bytes.NewReader([]byte("yourObjectValueByteArray")),
    )
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 下载时主动解密。body, err := cryptoBucket.GetObject("<yourObjectName>")
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }
    defer func(b *io.ReadCloser) {err = (*b).Close()
        if err != nil {log.Println("Error:", err)
        }
    }(&body)

    data, err := ioutil.ReadAll(body)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }
    fmt.Println("data:", string(data))
}

版本控制

版本控制以回滚至任一历史版本的形式,为 谬误笼罩 谬误删除 提供容错空间。

版本控制的一些 限度

  1. 与合规保留策略无奈同时配置
  2. 开启版本控制的 Bucket,x-oss-forbid-overwrite申请头将不再失效
  3. 不倡议同时开明 OSS-HDFS 服务并设置保留策略

版本控制有三个状态:未开启 开启 暂停

package main

import (
    "fmt"
    "os"

    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    // 创立 Client 实例。client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>",)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 创立 Bucket 实例。err = client.CreateBucket("<yourBucketName>")
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 开启版本控制。config := oss.VersioningConfig{Status: "Enabled"}
    err = client.SetBucketVersioning("<yourBucketName>", config)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 暂停版本控制。config.Status = "Suspended"
    err = client.SetBucketVersioning("<yourBucketName>", config)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }
}

防盗链

OSS通过比照 request headerReferer与配置规定是否统一来判断容许或回绝该申请。

package main

import (
    "fmt"
    "os"

    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    // 创立 Client 实例。client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 初始化 Referer 白名单。反对通配符星号(*)和问号(?)。referers := []string{
        "http://www.aliyun.com",
        "http://www.???.aliyuncs.com",
        "http://www.*.com",
    }

    // 设置 Referer 白名单,并禁止空 Referer
    // 留神:如果你配置了白名单但容许空 Referer,终局会很生硬...
    err = client.SetBucketReferer("yourBucketName", referers, false)
    if err != nil {fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 查问 Bucket Referer
    res, e := client.GetBucketReferer("yourBucketName")
    if e != nil {fmt.Println("Error:", e)
        os.Exit(-1)
    }
    fmt.Println(res.RefererList, res.AllowEmptyReferer)
}

合规保留策略

合规保留策略容许用户以“不可删除、不可篡改”形式保留和应用数据,合乎美国证券交易委员会(SEC)和金融业监管局(FINRA)的合规要求。

package main

import (
    "fmt"
    "os"

    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    // 创立 OSSClient 实例。client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret",)
    if err != nil {handleError(err)
    }

    // 初始化 WORM 规定(锁定 60 天)。// 最短锁定 1 天,最长锁定 70 年。wormID, e := client.InitiateBucketWorm("examplebucket", 60)
    if e != nil {handleError(e)
    }

    /*
        初始化后的 24 小时内,WORM 处于 InProgress 状态。在此期间,能够提交锁定,或者删除。若在此期间即未提交锁定也未删除,则 WORM 主动生效。*/

    // 提交锁定
    err = client.CompleteBucketWorm("examplebucket", wormID)
    if err != nil {handleError(err)
    }

    // 或者删除
    /*
        err = client.AbortBucketWorm("examplebucket")
        if err != nil {handleError(err)
        }
    */

    // 通过 Bucket 查问 WORM
    wormConfiguration, er := client.GetBucketWorm("examplebucket")
    if er != nil {handleError(er)
    }

    // WORM 一旦提交锁定,在解锁日期前,WORM 和 Bucket 内的所有 Object 均不反对删除。// 但能够缩短锁定期:err = client.ExtendBucketWorm("examplebucket", 180, wormConfiguration.WormId,)
    if err != nil {handleError(err)
    }
}

func handleError(err error) {fmt.Println("Error:", err)
    os.Exit(-1)
}

日志

package main

import (
    "fmt"
    "os"

    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    // 创立 OSSClient 实例。client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret",)
    if err != nil {handleError(err)
    }

    // 开启
    // 将 examplebucket 的日志存入 destbucket。err = client.SetBucketLogging("examplebucket", "destbucket", "log/", true)
    if err != nil {handleError(err)
    }

    // 查问
    res, e := client.GetBucketLogging("examplebucket")
    if e != nil {handleError(e)
    }
    fmt.Println(res.LoggingEnabled.TargetBucket, res.LoggingEnabled.TargetPrefix,)

    // 敞开
    err = client.DeleteBucketLogging("examplebucket")
    if err != nil {handleError(err)
    }
}

func handleError(err error) {fmt.Println("Error:", err)
    os.Exit(-1)
}

细节

避免意外笼罩

默认状况下,如果上传的文件与已有文件同名,则笼罩已有文件。
为避免文件被意外笼罩,能够在上传申请的 Header 中携带参数x-oss-forbid-overwrite,并指定其值为true

防止批改门路

OSS能够通过一些操作来模仿相似文件夹的性能,然而代价十分低廉。

比方重命名目录,心愿将 test1 目录重命名成 test2,那么OSS 的实际操作是将所有以 test1/ 结尾的 Object 都从新复制成以 test2/ 结尾的Object

这是一个十分耗费资源的操作。因而在应用 OSS 的时候要 尽量避免 相似的操作。

性能与扩展性最佳实际

Object Key 不要应用程序前缀!!!
Object Key 不要应用程序前缀!!!
Object Key 不要应用程序前缀!!!


阿里云 对象存储 OSS

正文完
 0