2.3 Minio使用
2.3.1 Minio介绍
官网:MinIO | 用于AI的S3 & Kubernetes原生对象存储
MinIO是一个开源的分布式对象存储服务器,支持S3协议并且可以在多节点上实现数据的高可用和容错。它采用Go语言开发,拥有轻量级、高性能、
易部署等特点,并且可以自由选择底层存储介质。
MinIO的主要特点包括:
1、高性能:MinIO基于GO语言编写,具有高速、轻量级、高并发等性能特点,还支持多线程和缓存等机制进行优化,可以快速地处理大规模数据。
2、可扩展性:MinIO采用分布式存储模式,支持水平扩展,通过增加节点数量来扩展存储容量和性能,支持自动数据迁移和负载均衡。
3、安全性:MinIO提供了多种安全策略,如访问控制列表(ACL)、服务端加密(SSE)、传输层安全性(TLS)等,可以保障数据安全和隐私。
4、兼容性:MinIO兼容AWS S3 API,还支持其他云服务提供商的API,比如GCP、Azure等,可以通过简单的配置实现互操作性。
5、简单易用:MinIO的部署和管理非常简单,只需要运行一个二进制包即可启动服务,同时提供了Web界面和命令行工具等方便的管理工具。
S3协议是Amazon Web Services (AWS) 提供的对象存储服务(Simple Storage Service)的API协议。它是一种 RESTful风格的Web服务接口,使
用HTTP/HTTPS协议进行通信,支持多种编程语言和操作系统,并实现了数据的可靠存储、高扩展性以及良好的可用性。
2.3.2 Minio安装
官网地址:MinIO对象存储 Container — MinIO中文文档 | MinIO Container中文文档
具体命令:
// 创建数据存储目录 mkdir -p ~/minio/data // 创建minio docker run \ -p 9001:9000 \ -p 9090:9090 \ --name minio \ -v ~/minio/data:/data \ -e "MINIO_ROOT_USER=admin" \ -e "MINIO_ROOT_PASSWORD=admin123456" \ -d \ quay.io/minio/minio server /data --console-address ":9090"
2.3.3 Minio入门
本章节会给大家介绍一下如何通过Java客户端操作Minio,可以参考官网地址。
官网地址:Java Quickstart Guide — MinIO Object Storage for Linux
具体步骤:
1、加入如下依赖
<!-- common-util模块中加入如下依赖 --> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.5.2</version> </dependency>
2、示例代码
public class FileUploadTest { public static void main(String[] args) throws Exception { // 创建一个Minio的客户端对象 MinioClient minioClient = MinioClient.builder() .endpoint("http://192.168.136.142:9001") .credentials("admin", "admin123456") .build(); boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket("spzx-bucket").build()); // 如果不存在,那么此时就创建一个新的桶 if (!found) { minioClient.makeBucket(MakeBucketArgs.builder().bucket("spzx-bucket").build()); } else { // 如果存在打印信息 System.out.println("Bucket 'spzx-bucket' already exists."); } FileInputStream fis = new FileInputStream("D://images//1.jpg") ; PutObjectArgs putObjectArgs = PutObjectArgs.builder() .bucket("spzx-bucket") .stream(fis, fis.available(), -1) .object("1.jpg") .build(); minioClient.putObject(putObjectArgs) ; // 构建fileUrl String fileUrl = "http://192.168.136.142:9001/spzx-bucket/1.jpg" ; System.out.println(fileUrl); } }
注意:设置minio的中该桶的访问权限为public,如下所示:
2.4 上传文件接口
2.4.1 FileUploadController
上传文件的表现层代码:
@RestController @RequestMapping("/admin/system") public class FileUploadController { @Autowired private FileUploadService fileUploadService ; @PostMapping(value = "/fileUpload") public Result<String> fileUploadService(@RequestParam(value = "file") MultipartFile multipartFile) { String fileUrl = fileUploadService.fileUpload(multipartFile) ; return Result.build(fileUrl , ResultCodeEnum.SUCCESS) ; } }
2.4.2 FileUploadService
上传文件的业务层代码:
@Service public class FileUploadServiceImpl implements FileUploadService { @Autowired private MinioProperties minioProperties ; @Override public String fileUpload(MultipartFile multipartFile) { try { // 创建一个Minio的客户端对象 MinioClient minioClient = MinioClient.builder() .endpoint(minioProperties.getEndpointUrl()) .credentials(minioProperties.getAccessKey(), minioProperties.getSecreKey()) .build(); // 判断桶是否存在 boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioProperties.getBucketName()).build()); if (!found) { // 如果不存在,那么此时就创建一个新的桶 minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioProperties.getBucketName()).build()); } else { // 如果存在打印信息 System.out.println("Bucket 'spzx-bucket' already exists."); } // 设置存储对象名称 String extFileName = FileNameUtils.getExtension(multipartFile.getOriginalFilename()); String fileName = new SimpleDateFormat("yyyyMMdd") .format(new Date()) + "/" + UUID.randomUUID().toString().replace("-" , "") + "." + extFileName; PutObjectArgs putObjectArgs = PutObjectArgs.builder() .bucket(minioProperties.getBucketName()) .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1) .object(fileName) .build(); minioClient.putObject(putObjectArgs) ; return minioProperties.getEndpointUrl() + "/" + minioProperties.getBucketName() + "/" + fileName ; } catch (Exception e) { throw new RuntimeException(e); } } }
2.4.3 MinioProperties
将构建MinioClient所对应的参数定义到配置文件中,然后通过该实体类封装该配置文件中的内容。
@Data @ConfigurationProperties(prefix="spzx.minio") //读取节点 public class MinioProperties { private String endpointUrl; private String accessKey; private String secreKey; private String bucketName; }
2.4.4 配置文件内容
在配置文件中添加Minio的相关配置
# 自定义配置 spzx: minio: endpointUrl: http://192.168.136.142:9001 accessKey: admin secreKey: admin123456 bucketName: sph
通过postman进行测试。
当你已有桶并且配置了public后可以直接
package com.atguigu.spzx.manager.service.imp;
import cn.hutool.core.date.DateTime;
import com.atguigu.spzx.manager.service.FileUploadService;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
* @version: java version 1.8
* @Author: Mr Orange
* @description: 该类是文件上传服务的实现类,实现了 FileUploadService 接口中的文件上传方法
* @date: 2025-02-06 13:31
*/
@Service // 使用 Spring 的 @Service 注解,将该类标记为服务层组件,以便 Spring 进行管理
public class FileUploadServiceImpl implements FileUploadService {
/**
* 实现文件上传的具体逻辑
* @param multipartFile 从客户端接收到的上传文件对象
* @return 上传后文件的访问 URL
* @throws ServerException 服务器端异常
* @throws InsufficientDataException 数据不足异常
* @throws ErrorResponseException 错误响应异常
* @throws IOException 输入输出异常
* @throws NoSuchAlgorithmException 不支持的算法异常
* @throws InvalidKeyException 无效密钥异常
* @throws InvalidResponseException 无效响应异常
* @throws XmlParserException XML 解析异常
* @throws InternalException 内部异常
*/
@Override
public String fileUpload(MultipartFile multipartFile) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
// 1. 创建 MinIO 客户端
// 使用 MinioClient 的构建器模式创建客户端实例
// .endpoint("http://192.168.153.128:9002") 指定 MinIO 服务的端点地址
// .credentials("admin", "admin123456") 指定访问 MinIO 服务所需的凭证(用户名和密码)
MinioClient minioClient = MinioClient.builder()
.endpoint("http://192.168.153.128:9002")
.credentials("admin", "admin123456")
.build();
// 2. 处理上传文件的文件名
// 获取上传文件的原始文件名,并在前面添加 "avatar/" 作为文件的存储目录
String originalFilename ="avatar"+"/"+ multipartFile.getOriginalFilename();
// 3. 构建上传文件所需的参数对象
// 使用 PutObjectArgs 的构建器模式构建上传文件的参数
// .bucket("spzx-1") 指定要上传到的 MinIO 存储桶名称
// .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1) 指定上传文件的输入流、文件大小,-1 表示使用默认的分块大小
// .object(originalFilename) 指定上传后文件在存储桶中的对象名称
PutObjectArgs putObjectArgs = PutObjectArgs.builder()
.bucket("spzx-1")
.stream(multipartFile.getInputStream(), multipartFile.getSize(), -1)
.object(originalFilename)
.build();
// 4. 执行文件上传操作
// 调用 MinioClient 的 putObject 方法将文件上传到 MinIO 存储桶中
minioClient.putObject(putObjectArgs);
// 5. 生成并返回上传后文件的访问 URL
// 获取当前日期并格式化为 "/yyyy/MM/dd" 的字符串形式
String timeStr = new DateTime().toString("/yyyy/MM/dd");
// 构建文件的访问 URL,格式为 "http://192.168.153.128:9002/spzx-1/avatar/文件名"
String url ="http://192.168.153.128:9002/"+"spzx-1"+"/"+originalFilename;
return url;
}
}