S3 协议使用
MyObj 提供完整的 AWS S3 兼容 API,可以使用 MinIO SDK、AWS SDK 或其他 S3 兼容工具进行访问。
S3服务与MyObj盘内数据互通,可以互相访问。同样,S3服务也受制于用户可用空间大小限制,隔离原则也同理。
🎯 概述
MyObj S3 服务完全兼容 AWS S3 协议,支持绝大部分核心功能和高级特性,包括:
- ✅ Bucket 操作(创建、删除、列表)
- ✅ Object 操作(上传、下载、删除、列表)
- ✅ Multipart Upload(大文件分片上传)
- ✅ 版本控制
- ✅ 预签名 URL
- ✅ CORS 配置
- ✅ 对象标签
- ✅ ACL(访问控制列表)
- ✅ Bucket 策略
- ✅ 生命周期管理
- ✅ 服务端加密(SSE-S3)
🚀 快速开始
1. 启用 S3 服务
编辑 config.toml:
toml
[s3]
# 是否启用 S3 服务
enable = true
# 区域名称
region = "us-east-1"
# 是否与主服务共用端口(true: 共用 8080,false: 使用独立端口)
share_port = false
# 独立端口(当 share_port = false 时生效)
port = 9000
# S3 API 路径前缀(留空表示根路径 /)
path_prefix = ""2. 创建 API Key
S3 访问需要使用 API Key 作为凭证:
- 登录 Web 界面
- 点击头像进入"系统设置" → "API Key"
- 创建新的 API Key
- 保存 API Key ID 和 S3 Secret Key
3. 使用 SDK
Go 语言 - MinIO SDK
go
package main
import (
"context"
"log"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
func main() {
// 初始化客户端
client, err := minio.New("localhost:9000", &minio.Options{
Creds: credentials.NewStaticV4("your-api-key-id", "your-secret-key", ""),
Secure: false,
Region: "us-east-1",
})
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// 列出所有 Bucket
buckets, err := client.ListBuckets(ctx)
if err != nil {
log.Fatal(err)
}
for _, bucket := range buckets {
log.Printf("Bucket: %s, Created: %v\n", bucket.Name, bucket.CreationDate)
}
// 创建 Bucket
err = client.MakeBucket(ctx, "my-bucket", minio.MakeBucketOptions{
Region: "us-east-1",
})
if err != nil {
log.Fatal(err)
}
log.Println("Bucket created successfully")
}Java 语言 - AWS SDK
Maven 依赖:
xml
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>netty-nio-client</artifactId>
</dependency>Java 代码示例:
java
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;
import java.net.URI;
public class S3Example {
public static void main(String[] args) {
// 创建 S3 客户端
S3Client s3Client = S3Client.builder()
.endpointOverride(URI.create("http://localhost:9000"))
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create("your-access-key-id", "your-secret-key")
))
.region(Region.US_EAST_1)
.forcePathStyle(true) // 重要:使用路径风格
.build();
// MyObj 支持自动创建存储桶,首次上传时会自动创建
// 上传对象(如果 Bucket 不存在会自动创建)
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket("my-bucket") // Bucket 会自动创建
.key("object-key")
.contentType("text/plain")
.acl(ObjectCannedACL.PRIVATE) // 设置 ACL:私有
.build();
s3Client.putObject(putObjectRequest,
software.amazon.awssdk.core.sync.RequestBody.fromString("Hello MyObj"));
// 下载对象
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
.bucket("my-bucket")
.key("object-key")
.build();
String content = s3Client.getObjectAsBytes(getObjectRequest)
.asUtf8String();
System.out.println("Content: " + content);
s3Client.close();
}
}ACL 配置说明:
MyObj S3 支持标准的 S3 Canned ACL,上传对象时可以设置:
java
// 私有访问(默认)
.acl(ObjectCannedACL.PRIVATE)
// 公开读
.acl(ObjectCannedACL.PUBLIC_READ)
// 公开读写
.acl(ObjectCannedACL.PUBLIC_READ_WRITE)
// 认证用户读
.acl(ObjectCannedACL.AUTHENTICATED_READ)
// Bucket 所有者读
.acl(ObjectCannedACL.BUCKET_OWNER_READ)
// Bucket 所有者完全控制
.acl(ObjectCannedACL.BUCKET_OWNER_FULL_CONTROL)支持的 ACL 类型:
PRIVATE- 私有访问,仅所有者可访问PUBLIC_READ- 公开读,所有人可读取PUBLIC_READ_WRITE- 公开读写,所有人可读取和写入AUTHENTICATED_READ- 认证用户读,所有认证用户可读取BUCKET_OWNER_READ- Bucket 所有者读BUCKET_OWNER_FULL_CONTROL- Bucket 所有者完全控制
注意:MyObj 支持自动创建存储桶,无需手动调用 createBucket()。
📋 功能详解
Bucket 操作
创建 Bucket
go
err := client.MakeBucket(ctx, "my-bucket", minio.MakeBucketOptions{
Region: "us-east-1",
})列出 Bucket
go
buckets, err := client.ListBuckets(ctx)删除 Bucket
go
err := client.RemoveBucket(ctx, "my-bucket")Object 操作
上传对象
Go 语言:
go
info, err := client.FPutObject(ctx, "my-bucket", "object-key", "local-file.pdf", minio.PutObjectOptions{
ContentType: "application/pdf",
})Java 语言:
java
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket("my-bucket")
.key("object-key")
.contentType("application/pdf")
.acl(ObjectCannedACL.PRIVATE) // 设置 ACL
.build();
s3Client.putObject(putObjectRequest, RequestBody.fromFile(new File("local-file.pdf")));下载对象
go
err := client.FGetObject(ctx, "my-bucket", "object-key", "local-file.pdf", minio.GetObjectOptions{})列出对象
go
objectCh := client.ListObjects(ctx, "my-bucket", minio.ListObjectsOptions{
Prefix: "folder/",
Recursive: true,
})
for object := range objectCh {
log.Printf("Object: %s, Size: %d\n", object.Key, object.Size)
}Multipart Upload
对于大文件,使用分片上传:
go
// 初始化分片上传
uploadID, err := client.NewMultipartUpload(ctx, "my-bucket", "large-file.zip", minio.PutObjectOptions{})
// 上传分片
part1, err := client.PutObjectPart(ctx, "my-bucket", "large-file.zip", uploadID, 1, file1, -1, minio.PutObjectPartOptions{})
part2, err := client.PutObjectPart(ctx, "my-bucket", "large-file.zip", uploadID, 2, file2, -1, minio.PutObjectPartOptions{})
// 完成分片上传
parts := []minio.CompletePart{part1, part2}
_, err = client.CompleteMultipartUpload(ctx, "my-bucket", "large-file.zip", uploadID, parts, minio.PutObjectPartOptions{})版本控制
启用版本控制
go
err := client.SetBucketVersioning(ctx, "my-bucket", minio.BucketVersioningConfiguration{
Status: "Enabled",
})列出对象版本
go
objectCh := client.ListObjects(ctx, "my-bucket", minio.ListObjectsOptions{
WithVersions: true,
})预签名 URL
生成预签名 URL,允许临时访问:
go
// GET 预签名 URL(下载)
url, err := client.PresignedGetObject(ctx, "my-bucket", "object-key", time.Hour*24, nil)
// PUT 预签名 URL(上传)
url, err := client.PresignedPutObject(ctx, "my-bucket", "object-key", time.Hour*24)CORS 配置
go
corsConfig := minio.BucketCors{
CORSRules: []minio.CORSRule{
{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"GET", "PUT", "POST", "DELETE"},
AllowedHeaders: []string{"*"},
MaxAgeSeconds: 3600,
},
},
}
err := client.SetBucketCors(ctx, "my-bucket", &corsConfig)🔧 配置说明
Bucket 命名规范
符合 AWS S3 Bucket 命名规范:
- 长度在 3-63 个字符之间
- 只能包含小写字母、数字、点(.)和连字符(-)
- 必须以字母或数字开头和结尾
- 不能包含连续的点
- 不能是 IP 地址格式
认证方式
使用 AWS Signature V4 签名机制:
- Access Key ID: 对应 MyObj 的 API Key
- Secret Access Key: 对应 API Key 的私钥
- 签名计算方式与 AWS S3 完全兼容
Bucket 映射
- 每个 Bucket 对应一个用户虚拟目录
- 一个用户可以创建多个 Bucket
- Bucket 名称在用户空间内必须唯一
自动创建存储桶
MyObj S3 支持自动创建存储桶:
- 首次使用时会自动创建配置的 Bucket
- 无需手动创建,简化配置流程
- 自动处理 Bucket 命名和权限设置
📊 使用场景
场景 1: 备份工具集成
使用 S3 兼容的备份工具(如 rclone、duplicati)进行文件备份:
bash
# rclone 配置
rclone config
# 选择 S3 类型
# Endpoint: http://your-domain:8080
# Access Key ID: your-access-key-id
# Secret Access Key: your-secret-key场景 2: 应用集成
在应用中使用 S3 SDK 存储文件:
go
// 上传用户头像
_, err := client.FPutObject(ctx, "user-avatars", userID+".jpg", avatarPath, minio.PutObjectOptions{})场景 3: 静态网站托管
结合 CDN 使用 S3 存储静态资源。
🔍 故障排查
签名验证失败
Error: SignatureDoesNotMatch解决方案:
- 检查 Access Key 和 Secret Key 是否正确
- 确认时间同步(签名计算依赖时间戳)
- 查看日志中的详细错误信息
Bucket 已存在
Error: BucketAlreadyExists解决方案:
- Bucket 名称在用户空间内必须唯一
- 使用不同的 Bucket 名称
Bucket 名称不合法
Error: InvalidBucketName解决方案:
- 检查 Bucket 名称是否符合 S3 命名规范
- 只使用小写字母、数字、点和连字符
- 长度 3-63 个字符
🔗 框架集成
Java 框架集成
- RuoYi-Plus 框架集成 - 在 RuoYi-Vue-Plus 或 RuoYi-Cloud-Plus 中使用 MyObj S3
其他集成方式
MyObj S3 兼容所有支持 AWS S3 协议的 SDK 和工具,包括:
- AWS SDK (Java, Python, JavaScript, Go, .NET 等)
- MinIO SDK (Go, Java, Python, JavaScript 等)
- rclone、s3cmd 等命令行工具
- 各种备份工具(duplicati、restic 等)
