MINIO对象存储管理的使用
1.前言
1.1 Minio定义
Minio是一个高性能的分布式对象存储系统,专为云原生应用设计。它是开源的,兼容 Amazon S3 API,允许用户在私有云或公有云环境中存储和管理海量数据。
1.2 Minio特点
- 高性能:
MinIO 采用高效的存储架构,能够提供极低的延迟和高吞吐量,适合大数据和机器学习工作负载。 - S3 兼容性:
MinIO 完全兼容 Amazon S3 API,使得现有的 S3 应用和工具可以轻松迁移到 MinIO,而无需进行大量修改。 - 简易部署:
MinIO 的部署非常简单,支持容器化(如 Docker 和 Kubernetes),可以快速在各种环境中运行。 - 高可用性和可扩展性:
支持分布式架构,可以水平扩展以满足不断增长的数据存储需求,同时提供高可用性和容错能力。 - 安全性:
提供多种安全功能,包括数据加密(静态和传输中的加密)、身份验证和访问控制,确保数据的安全性。 - 多种存储后端支持:
MinIO 可以与多种存储后端集成,如本地磁盘、云存储等,灵活适应不同的存储需求。
2.图片上传流程分析
这里本人通过自己的Spring Boot项目,在浏览器中上传了一张照片,解释了一下上传图片的流程
3.Minio使用
接下来我将使用我自己的一个spring boot项目,展示一下Minion的使用(我使用的是一个我部署在自己虚拟机上的一个Minio)
3.1 引入Minio Maven依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
</dependency>
3.2 为了方便管理,将Minio的一些属性配置在application中,并用用一个类将其映射到其中
minio:
endpoint: http://192.168.88.134:9000 #http://<hostname>:<port> 主机号和端口号
access-key: minioadmin #<access-key>用户名
secret-key: minioadmin #<secret-key>密码
bucket-name: lease #<bucket-name>存储桶名称
3.3 创建Minio属性一一对应配置类
@ConfigurationProperties(prefix = "minio")
@Data
public class MinioProperties {
private String endpoint;
private String accessKey;
private String secretKey;
private String bucketName;
}
3.4 使用配置类来创建和管理外部服务(如 MinIO)客户端
@Configuration
@EnableConfigurationProperties(MinioProperties.class)
public class MinioConfiguration {
@Autowired
private MinioProperties properties;
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(properties.getEndpoint())
.credentials(properties.getAccessKey(), properties.getSecretKey()).build();
}
}
3.5 service方法中的使用
在ServiceImpl中增加如下内容
@Service
public class FileServiceImpl implements FileService {
@Autowired
private MinioProperties properties;
@Autowired
private MinioClient client;
@Override
public String upload(MultipartFile file) throws ServerException, InsufficientDataException, ErrorResponseException, IOException,
NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
//判断该存储桶是否存在,如果没有则创建一个新的存储桶
boolean bucketExists = client.bucketExists(BucketExistsArgs.builder().bucket(properties.getBucketName()).build());
if (!bucketExists) {
client.makeBucket(MakeBucketArgs.builder().bucket(properties.getBucketName()).build());
client.setBucketPolicy(SetBucketPolicyArgs
.builder()
.bucket(properties.getBucketName())
.config(createBucketPolicyConfig(properties.getBucketName())).build());
}
//给上传文件命名filename
String filename = new SimpleDateFormat("yyyyMMdd").format(new Date()) + "/" + UUID.randomUUID() + "-" + file.getOriginalFilename();
client.putObject(PutObjectArgs.builder().
bucket(properties.getBucketName()).
object(filename).
stream(file.getInputStream(), file.getSize(), -1).
contentType(file.getContentType()).build());
//返回文件url = String.join("/", properties.getEndpoint(), properties.getBucketName(), filename)
return String.join("/", properties.getEndpoint(), properties.getBucketName(), filename);
}
private String createBucketPolicyConfig(String bucketName) {
return """
{
"Statement" : [ {
"Action" : "s3:GetObject",
"Effect" : "Allow",
"Principal" : "*",
"Resource" : "arn:aws:s3:::%s/*"
} ],
"Version" : "2012-10-17"
}
""".formatted(bucketName);
}
}
注意:
上述createBucketPolicyConfig方法的作用是生成用于描述指定bucket访问权限的JSON字符串。最终生成的字符串格式如下,其表示,允许(Allow)所有人(*)获取(s3:GetObject)指定桶()的内容。
{
"Statement" : [ {
"Action" : "s3:GetObject",
"Effect" : "Allow",
"Principal" : "*",
"Resource" : "arn:aws:s3:::<bucket-name>/*"
} ],
"Version" : "2012-10-17"
}
这里设置的是允许所有人都可以查看