1. Minio介绍
1.1 什么是Minio
Minio 是一个基于Apache License v2.0开源协议的对象存储服务。它可以运行在多种操作系统上,包括 Linux 和 Windows 等。
它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5TB不等。
Minio官网地址:MinIO | 用于AI的S3 & Kubernetes原生对象存储
Minio官方文档:技术文档
1.2 Minio的特点
-
简单易用:
Minio
的安装和配置非常简单,只需要下载并运行相应的二进制文件即可。它提供了一个Web UI,可以通过界面管理存储桶和对象。 -
可扩展性: Minio可以轻松地扩展到多个节点,以提供高可用性和容错能力。它支持多种部署模式,包括单节点、主从复制和集群等。
-
高可用性: Minio提供了多种机制来保证数据的可靠性和可用性,包括冗余备份、数据复制和故障转移等。
-
安全性: Minio提供了多种安全机制来保护数据的机密性和完整性,包括SSL/TLS加密、访问控制和数据加密等。
-
多语言支持: Minio支持多种编程语言,包括Java、Python、Ruby和Go等。
-
社区支持: Minio是一个开源项目,拥有庞大的社区支持和贡献者。它的源代码可以在GitHub上获得,并且有一个活跃的邮件列表和论坛。
-
对象存储: Minio的核心功能是对象存储。它允许用户上传和下载任意数量和大小的对象,并提供了多种API和SDK来访问这些对象。
-
块存储:
Minio
还支持块存储,允许用户上传和下载大型文件(例如图像或视频)。块存储是一种快速、高效的方式来处理大型文件。 -
文件存储: Minio还支持文件存储,允许用户上传和下载单个文件。文件存储是一种简单、快速的方式来处理小型文件。
2. Minio安装
2.1 Windows安装Minio
2.1.1 在D盘创建一个Minio的文件夹,并在里面建两个空的文件夹,一个是bin,一个是data
bin文件夹放下载的exe程序
data文件夹存储文件
2.1.2 下载Minio
下载地址:MinIO下载和安装 | 用于创建高性能对象存储的代码和下载内容
2.1.3 把下载好的 minio.exe 放到 2.1.1 创建的 bin 文件夹下
2.1.4 启动Minio
注意:不要双击运行!!!不要双击运行!!!不要双击运行!!!
在bin文件夹下,点击路径输入cmd,回车打开cmd窗口,或者通过命令定位到【D:\Minio\bin】文件夹中,输入下方命令,启动MinIO服务,不需要进行其他操作
.\minio.exe server D:\Minio\data
注意:
启动后会显示minio的访问地址,默认的用户名和密码。
关闭窗口将停止minio服务器并结束该过程。
2.1.5 浏览器打开上面地址,输入用户名,密码,进行访问
2.1.6 固定端口访问
.\minio.exe server D:\Minio\data --console-address :9001 --address :9000
客户端端口:--console-address :9001
服务器端口:--address :9000
2.1.7 修改用户名,密码
设置账号(至少3位):setx MINIO_ROOT_USER minioroot
设置密码(至少8位):setx MINIO_ROOT_PASSWORD minioroot
setx MINIO_ROOT_USER minioroot
setx MINIO_ROOT_PASSWORD minioroot
2.18 创建 bat 启动文件
创建 runMinio.txt,复制下面的命令保存,修改文件名 runMinio.bat
cmd /c "cd /d D:\Minio\bin&& .\minio.exe server D:\Minio\data
cmd /c "cd /d D:\Minio\bin&& .\minio.exe server D:\Minio\data --console-address :9001 --address :9000
下面的命令存后,双击运行,cmd窗口只是一闪而过,会加到服务里面
打开任务管理器,会发现minio服务是启动的,但是原来的cmd窗口已经被隐藏了
@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit
:begin
REM
cmd /c "cd /d D:\Minio\bin&& .\minio.exe server D:\Minio\data
@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit
:begin
REM
cmd /c "cd /d D:\Minio\bin&& .\minio.exe server D:\Minio\data --console-address :9001 --address :9000
2.2 Linux安装Minio
2.2.1 在 home 路径下面创建 Minio 文件夹
2.2.2 下载
wget https://dl.min.io/server/minio/release/linux-amd64/minio
2.2.3 添加执行权限给MinIO文件
chmod +x minio
2.2.4 在 home/Minio下面创建 data 文件夹,做为文件存储路径
2.2.5 启动
./minio server /home/Minio/data
./minio.exe server /home/Minio/data --console-address :9001 --address :9000
后台执行
nohup /home/Minio/minio server /home/Minio/data --console-address :9001 --address :9000 > /dev/null 2>&1 &
2.3 创建 Bucket
2.3 创建 Access Key
3. Springboot接入Minio
3.1创建Springboot项目
3.2 pom文件添加依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.3.4</version>
</dependency>
3.3 application.yml添加配置
#minio配置(下面四个都要替换成自己的)
minio:
access-key: li5fasdfaeWFR344W2
secret-key: p4VIZ23948ASDFJAjasdif2UFSDFc9b
url: http://169.254.19.42:9000
bucket-name: file
3.4 编写MinioConfig 配置类
package com.minio.config;
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
private String accessKey;
private String secretKey;
private String url;
private String bucketName;
@Bean
public MinioClient minioClient(){
return MinioClient.builder()
.region("cn-north-1")
.endpoint(url)
.credentials(accessKey,secretKey)
.build();
}
}
3.5 编写MinioUtil工具类
package com.minio.utils;
import com.minio.config.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.concurrent.TimeUnit;
@Component
public class MinioUtil {
@Autowired
private MinioClient minioClient;
@Autowired
private MinioConfig configuration;
/**
* 判断bucket是否存在,不存在则创建
*/
public boolean existBucket(String bucketName) {
boolean exists;
try {
exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
if (!exists) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
exists = true;
}
} catch (Exception e) {
e.printStackTrace();
exists = false;
}
return exists;
}
/**
* 删除bucket
*/
public Boolean removeBucket(String bucketName) {
try {
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 上传文件
*
* @param file 文件
* @param fileName 文件名称
*/
public void upload(MultipartFile file, String fileName) {
// 使用putObject上传一个文件到存储桶中。
try {
InputStream inputStream = file.getInputStream();
minioClient.putObject(PutObjectArgs.builder()
.bucket(configuration.getBucketName())
.object(fileName)
.stream(inputStream, file.getSize(), -1)
.contentType(file.getContentType())
.build());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取文件访问地址(有过期时间)
*
* @param fileName 文件名称
* @param time 时间
* @param timeUnit 时间单位
*/
public String getExpireFileUrl(String fileName, int time, TimeUnit timeUnit) {
try {
return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(configuration.getBucketName())
.object(fileName)
.expiry(time, timeUnit).build());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取文件访问地址
*
* @param fileName 文件名称
*/
public String getFileUrl(String fileName) {
try {
return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(configuration.getBucketName())
.object(fileName)
.build()
);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 下载文件
*
* @param fileName 文件名称
*/
public void download(HttpServletResponse response, String fileName) {
InputStream in = null;
try {
// 获取对象信息
StatObjectResponse stat = minioClient.statObject(StatObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
response.setContentType(stat.contentType());
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
// 文件下载
in = minioClient.getObject(GetObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
IOUtils.copy(in, response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 删除文件
*
* @param fileName 文件名称
*/
public void delete(String fileName) {
try {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.6 编写UploadController
package com.minio.controller;
import com.minio.utils.MinioUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
/**
* @author liyh
*/
@RestController
@RequestMapping("/api")
public class UploadController {
@Autowired
private MinioUtil minioUtil;
/**
* 上传文件
*/
@PostMapping(value = "/upload")
public String uploadReport(MultipartFile[] files) {
for (MultipartFile file : files) {
String fileName = file.getOriginalFilename();
String rename = UUID.randomUUID().toString();
minioUtil.upload(file, rename);
}
return "上传成功";
}
/**
* 预览文件
*/
@GetMapping("/preview")
public String preview(String fileName) {
return minioUtil.getFileUrl(fileName);
}
/**
* 下载文件
*/
@GetMapping("/download")
public void download(String fileName, HttpServletResponse response) {
minioUtil.download(response, fileName);
}
/**
* 删除文件
*/
@GetMapping("/delete")
public String delete(String fileName) {
minioUtil.delete(fileName);
return "删除成功";
}
}
4. 启动项目测试
4.1 上传文件
http://127.0.0.1:8088/api/upload
4.2 预览文件
http://127.0.0.1:8088/api/preview?fileName=
4.3 下载文件
http://127.0.0.1:8088/api/download?fileName=
4.4 删除文件
http://127.0.0.1:8088/api/delete?fileName=