可靠性: 完善 R2 备份恢复与对象生命周期

This commit is contained in:
tamakyi
2026-11-05 08:41:55 +08:00
parent 3e7719f200
commit 937e688cfa
32 changed files with 4151 additions and 231 deletions
+11 -14
View File
@@ -23,7 +23,6 @@ import (
"github.com/disintegration/imaging"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/wuhan005/gadget"
"github.com/tamakyi/TamaBox/internal/conf"
"github.com/tamakyi/TamaBox/internal/imagecheck"
@@ -189,19 +188,17 @@ func uploadPictureToS3(file multipart.File, fileHeader *multipart.FileHeader, as
return "", errors.Wrap(err, "get S3 client")
}
// 7. 上传到 R2
if err := gadget.Retry(5, func() error {
_, err := client.PutObject(context.Background(), &s3.PutObjectInput{
Bucket: aws.String(conf.Upload.ImageBucket),
Key: aws.String(key),
Body: bytes.NewReader(uploadData),
ContentLength: aws.Int64(int64(len(uploadData))),
ContentType: aws.String(contentType),
// key 含纳秒时间戳且内容不可变 → 可安全启用 immutable 强缓存,
// 避免每次页面加载都回源校验(曾导致头像/二维码 logo 每次重新下载)。
CacheControl: aws.String("public, max-age=31536000, immutable"),
})
return err
// 7. 上传到 R2。现有上传 API 不接收调用方 context,故显式标记为 TODO;
// PutObject 内部会为每次尝试设置独立超时,并对可取消 context 做退避。
if err := PutObject(context.TODO(), client, &s3.PutObjectInput{
Bucket: aws.String(conf.Upload.ImageBucket),
Key: aws.String(key),
Body: bytes.NewReader(uploadData),
ContentLength: aws.Int64(int64(len(uploadData))),
ContentType: aws.String(contentType),
// key 含纳秒时间戳且内容不可变 → 可安全启用 immutable 强缓存,
// 避免每次页面加载都回源校验(曾导致头像/二维码 logo 每次重新下载)。
CacheControl: aws.String("public, max-age=31536000, immutable"),
}); err != nil {
return "", errors.Wrap(err, "put object after retry")
}