【分布式文件存储系统Minio】2024.12保姆级教程
文章目录
- 1.介绍
- 1.分布式文件系统
- 2.基本概念
- 2.环境搭建
- 1.访问网址
- 2.账号密码都是minioadmin
- 3.创建一个桶
- 4.**Docker安装miniomc突破7天限制**
- 1.拉取镜像
- 2.运行容器
- 3.进行配置
- 1.格式
- 2.具体配置
- 4.查看桶
- 5.给桶开放权限
- 3.搭建minio模块
- 1.创建一个oss模块
- 1.在sun-common下创建
- 2.引入minio依赖
- 1.sun-dependencies 锁定版本
- 2.sun-common-oss 引入依赖
- 2.sun-common-oss 模块
- 1.概览
- 2.MinioConfig.java
- 3.FileInfo.java
- 4.MinioUtil.java
- 5.StorageAdapter.java
- 6.MinioStorageAdapter.java
- 3.sun-demo操作minio
- 1.引入sun-common-oss
- 2.application.yml 配置minio参数
- 3.暴露接口 MinioController.java
- 4.测试
1.介绍
1.分布式文件系统
2.基本概念
2.环境搭建
1.访问网址
http://ip:9090/
2.账号密码都是minioadmin
3.创建一个桶
4.Docker安装miniomc突破7天限制
1.拉取镜像
docker pull minio/mc:RELEASE.2023-11-15T22-45-58Z.fips
2.运行容器
docker run -it --entrypoint=/bin/sh minio/mc:RELEASE.2023-11-15T22-45-58Z.fips
3.进行配置
1.格式
mc config host add <ALIAS> <YOUR-S3-ENDPOINT> <YOUR-ACCESS-KEY> <YOUR-SECRET-KEY>
2.具体配置
mc config host add minio http://ip:9000 9i14IBbM2ysYVPDa52oK eXRpXcXcX5w4Tmy8HprUkemVi5zzrbpS4NksxxtU
4.查看桶
mc ls minio
5.给桶开放权限
mc anonymous set download minio/桶
3.搭建minio模块
1.创建一个oss模块
1.在sun-common下创建
2.引入minio依赖
1.sun-dependencies 锁定版本
<minio.version>8.2.0</minio.version>
<!-- minio依赖 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio.version}</version>
</dependency>
2.sun-common-oss 引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 继承父模块的版本和通用依赖 -->
<parent>
<groupId>com.sunxiansheng</groupId>
<artifactId>sun-common</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>sun-common-oss</artifactId>
<!-- 子模块的version,如果不写就默认跟父模块的一样 -->
<version>${children.version}</version>
<dependencies>
<!-- minio依赖 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
</dependency>
<!-- spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
2.sun-common-oss 模块
1.概览
2.MinioConfig.java
package com.sunxiansheng.oss.config;
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Description: minio配置管理
* @Author sun
* @Create 2024/5/31 9:22
* @Version 1.0
*/
@Configuration
public class MinioConfig {
/**
* minioUrl
*/
@Value("${minio.url}")
private String url;
/**
* minio账户
*/
@Value("${minio.accessKey}")
private String accessKey;
/**
* minio密码
*/
@Value("${minio.secretKey}")
private String secretKey;
/**
* 构造minioClient
*/
@Bean
public MinioClient getMinioClient() {
return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
}
}
3.FileInfo.java
package com.sunxiansheng.oss.entity;
import lombok.Data;
/**
* FileInfo类用于存储文件的基本信息,包括文件名、是否为目录的标志以及文件的ETag。
* 这个类可以在对象存储系统中用于描述文件的属性。
* @Author sun
* @Create 2024/5/31 9:47
* @Version 1.0
*/
@Data
public class FileInfo {
// 文件的名称
private String fileName;
// 指示该文件是否为目录的标志
private Boolean directoryFlag;
// 文件的ETag,用于标识文件的唯一性
private String etag;
}
4.MinioUtil.java
package com.sunxiansheng.oss.util;
import com.sunxiansheng.oss.entity.FileInfo;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
/**
* MinioUtil是一个用于与MinIO对象存储服务进行交互的工具类。
* 提供了一系列方法用于管理存储桶和对象,包括创建桶、上传文件、下载文件、删除文件等操作。
* @Author sun
* @Create 2024/5/31 9:30
* @Version 1.0
*/
@Component
public class MinioUtil {
@Resource
private MinioClient minioClient; // MinIO客户端实例,用于执行各种存储操作。
/**
* 创建存储桶。
* 如果指定名称的存储桶不存在,则创建它。
*
* @param bucket 存储桶的名称
* @throws Exception 如果创建存储桶时发生错误
*/
public void createBucket(String bucket) throws Exception {
boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
if (!exists) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
}
}
/**
* 上传文件到指定存储桶。
*
* @param inputStream 文件输入流
* @param bucket 存储桶的名称
* @param objectName 对象名称,即文件在存储桶中的名称
* @throws Exception 如果上传文件时发生错误
*/
public void uploadFile(InputStream inputStream, String bucket, String objectName) throws Exception {
minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName)
.stream(inputStream, -1, 5242889L).build());
}
/**
* 获取所有存储桶的名称列表。
*
* @return 存储桶名称的列表
* @throws Exception 如果获取存储桶列表时发生错误
*/
public List<String> getAllBucket() throws Exception {
List<Bucket> buckets = minioClient.listBuckets();
return buckets.stream().map(Bucket::name).collect(Collectors.toList());
}
/**
* 获取指定存储桶中的所有文件信息。
*
* @param bucket 存储桶的名称
* @return 文件信息列表,其中包含文件名、是否为目录标志和ETag
* @throws Exception 如果获取文件列表时发生错误
*/
public List<FileInfo> getAllFile(String bucket) throws Exception {
Iterable<Result<Item>> results = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucket).build());
List<FileInfo> fileInfoList = new LinkedList<>();
for (Result<Item> result : results) {
FileInfo fileInfo = new FileInfo();
Item item = result.get();
fileInfo.setFileName(item.objectName());
fileInfo.setDirectoryFlag(item.isDir());
fileInfo.setEtag(item.etag());
fileInfoList.add(fileInfo);
}
return fileInfoList;
}
/**
* 从指定存储桶下载文件。
*
* @param bucket 存储桶的名称
* @param objectName 对象名称,即文件在存储桶中的名称
* @return 文件输入流,用于读取下载的文件内容
* @throws Exception 如果下载文件时发生错误
*/
public InputStream downLoad(String bucket, String objectName) throws Exception {
return minioClient.getObject(
GetObjectArgs.builder().bucket(bucket).object(objectName).build()
);
}
/**
* 删除指定存储桶。
* 注意:存储桶必须为空才能被删除。
*
* @param bucket 存储桶的名称
* @throws Exception 如果删除存储桶时发生错误
*/
public void deleteBucket(String bucket) throws Exception {
minioClient.removeBucket(
RemoveBucketArgs.builder().bucket(bucket).build()
);
}
/**
* 删除指定存储桶中的文件。
*
* @param bucket 存储桶的名称
* @param objectName 对象名称,即要删除的文件在存储桶中的名称
* @throws Exception 如果删除文件时发生错误
*/
public void deleteObject(String bucket, String objectName) throws Exception {
minioClient.removeObject(
RemoveObjectArgs.builder().bucket(bucket).object(objectName).build()
);
}
/**
* 获取文件的预览URL。
* 该URL可以用于在浏览器中查看或下载文件。
*
* @param bucketName 存储桶的名称
* @param objectName 对象名称,即文件在存储桶中的名称
* @return 文件的预签名URL
* @throws Exception 如果获取预签名URL时发生错误
*/
public String getPreviewFileUrl(String bucketName, String objectName) throws Exception{
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(bucketName).object(objectName).build();
return minioClient.getPresignedObjectUrl(args);
}
}
5.StorageAdapter.java
package com.sunxiansheng.oss.adapter;
import com.sunxiansheng.oss.entity.FileInfo;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.List;
/**
* StorageAdapter接口定义了与对象存储服务交互的方法。
* 这些方法提供了基本的存储操作,如创建存储桶、上传和下载文件、获取文件信息等。
* @Author sun
* @Create 2024/5/31 10:03
* @Version 1.0
*/
public interface StorageAdapter {
/**
* 创建存储桶。
* 如果指定名称的存储桶不存在,则创建它。
*
* @param bucket 存储桶的名称
*/
void createBucket(String bucket);
/**
* 上传文件到指定存储桶。
*
* @param uploadFile 要上传的文件
* @param bucket 存储桶的名称
* @param objectName 对象名称,即文件在存储桶中的名称
*/
String uploadFile(MultipartFile uploadFile, String bucket, String objectName);
/**
* 获取所有存储桶的名称列表。
*
* @return 存储桶名称的列表
*/
List<String> getAllBucket();
/**
* 获取指定存储桶中的所有文件信息。
*
* @param bucket 存储桶的名称
* @return 文件信息列表,其中包含文件名、是否为目录标志和ETag
*/
List<FileInfo> getAllFile(String bucket);
/**
* 从指定存储桶下载文件。
*
* @param bucket 存储桶的名称
* @param objectName 对象名称,即文件在存储桶中的名称
* @return 文件输入流,用于读取下载的文件内容
*/
InputStream downLoad(String bucket, String objectName);
/**
* 删除指定存储桶。
* 注意:存储桶必须为空才能被删除。
*
* @param bucket 存储桶的名称
*/
void deleteBucket(String bucket);
/**
* 删除指定存储桶中的文件。
*
* @param bucket 存储桶的名称
* @param objectName 对象名称,即要删除的文件在存储桶中的名称
*/
void deleteObject(String bucket, String objectName);
/**
* 获取文件的访问URL。
* 该URL可以用于在浏览器中查看或下载文件。
* @param originalFilename 原始文件名
* @param bucket 存储桶的名称
* @param objectName 对象名称,即文件在存储桶中的名称
* @return 文件的URL
*/
public String getUrl(String originalFilename, String bucket, String objectName);
}
6.MinioStorageAdapter.java
package com.sunxiansheng.oss.adapter;
import com.sunxiansheng.oss.entity.FileInfo;
import com.sunxiansheng.oss.util.MinioUtil;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.List;
/**
* MinioStorageAdapter类实现了StorageAdapter接口,使用MinioUtil类与MinIO对象存储服务进行交互。
* 提供了一系列方法来管理存储桶和对象,包括创建桶、上传文件、下载文件、删除文件等操作。
* @Author sun
* @Create 2024/5/31 10:06
* @Version 1.0
*/
@Component
public class MinioStorageAdapter implements StorageAdapter {
@Resource
private MinioUtil minioUtil; // 使用MinioUtil工具类来执行存储操作
/**
* MinIO服务的URL。
* 该URL通常在配置文件中设置,用于构建文件访问的完整URL。
*/
@Value("${minio.url}")
private String url;
/**
* 创建存储桶。
* 使用MinioUtil工具类创建存储桶。
*
* @param bucket 存储桶的名称
*/
@Override
@SneakyThrows
public void createBucket(String bucket) {
minioUtil.createBucket(bucket);
}
// ============================== 文件上传后的URL:url + 桶名 + 上传时的objectName ==============================
/**
* 上传文件到指定存储桶,并返回可访问的url
* 使用提供的对象名称或文件的原始名称进行上传。
*
* @param uploadFile 要上传的文件
* @param bucket 存储桶的名称
* @param objectName 对象名称,表示完整的文件路径和名称
*/
@Override
@SneakyThrows
public String uploadFile(MultipartFile uploadFile, String bucket, String objectName) {
minioUtil.createBucket(bucket);
String finalObjectName = generateObjectName(uploadFile.getOriginalFilename(), objectName);
minioUtil.uploadFile(uploadFile.getInputStream(), bucket, finalObjectName);
return getUrl(uploadFile.getOriginalFilename(), bucket, objectName);
}
/**
* 自定义对象名的格式,上传时的对象名是什么格式,那么下载时的对象名也是什么格式
* url的格式就是 url + 桶名 + 对象名
*
* @param originalFilename 原始文件名字
* @param objectName 提供的对象名称
* @return 最终用于存储的对象名称
*/
private String generateObjectName(String originalFilename, String objectName) {
// 如果对象名为空,则使用文件的原始名称作为对象名
if (objectName == null) {
return originalFilename;
}
// 如果对象名不为空,则对象名 + / + 文件名作为对象名
return objectName + "/" + originalFilename;
}
/**
* 获取文件的访问URL。
* 该URL可以用于在浏览器中查看或下载文件。
*
* @param bucket 存储桶的名称
* @param objectName 对象名称,即文件在存储桶中的名称
* @return 文件的完整URL
*/
@Override
@SneakyThrows
public String getUrl(String originalFilename, String bucket, String objectName) {
// 首先生成对象名
String finalObjectName = generateObjectName(originalFilename, objectName);
// url的格式就是 url + 桶名 + 对象名
return url + "/" + bucket + "/" + finalObjectName;
}
// ============================== 文件上传后的URL:url + 桶名 + 上传时的objectName ==============================
/**
* 获取所有存储桶的名称列表。
*
* @return 存储桶名称的列表
*/
@Override
@SneakyThrows
public List<String> getAllBucket() {
return minioUtil.getAllBucket();
}
/**
* 获取指定存储桶中的所有文件信息。
*
* @param bucket 存储桶的名称
* @return 文件信息列表,其中包含文件名、是否为目录标志和ETag
*/
@Override
@SneakyThrows
public List<FileInfo> getAllFile(String bucket) {
return minioUtil.getAllFile(bucket);
}
/**
* 从指定存储桶下载文件。
*
* @param bucket 存储桶的名称
* @param objectName 对象名称,即文件在存储桶中的名称
* @return 文件输入流,用于读取下载的文件内容
*/
@Override
@SneakyThrows
public InputStream downLoad(String bucket, String objectName) {
return minioUtil.downLoad(bucket, objectName);
}
/**
* 删除指定存储桶。
* 注意:存储桶必须为空才能被删除。
*
* @param bucket 存储桶的名称
*/
@Override
@SneakyThrows
public void deleteBucket(String bucket) {
minioUtil.deleteBucket(bucket);
}
/**
* 删除指定存储桶中的文件。
*
* @param bucket 存储桶的名称
* @param objectName 对象名称,即要删除的文件在存储桶中的名称
*/
@Override
@SneakyThrows
public void deleteObject(String bucket, String objectName) {
minioUtil.deleteObject(bucket, objectName);
}
}
3.sun-demo操作minio
1.引入sun-common-oss
<!-- 引入sun-common-oss -->
<dependency>
<groupId>com.sunxiansheng</groupId>
<artifactId>sun-common-oss</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
2.application.yml 配置minio参数
# minio配置
minio:
url: http://ip:9000
accessKey: minioadmin
secretKey: minioadmin
3.暴露接口 MinioController.java
package com.sunxiansheng.user.controller;
import com.sunxiansheng.oss.adapter.StorageAdapter;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
/**
* Description:
* @Author sun
* @Create 2024/8/2 16:25
* @Version 1.0
*/
@RestController
public class MinioController {
@Resource
private StorageAdapter storageAdapter;
/**
* 上传文件并返回url
*/
@RequestMapping("/upload")
public String upload(MultipartFile uploadFile, String bucket, String objectName) throws Exception {
return storageAdapter.uploadFile(uploadFile, bucket, objectName);
}
}