Minio实现分布式存储
MinIO 是在 GNU Affero 通用公共许可证 v3.0 下发布的高性能对象存储。它与 Amazon S3 云存储服务 API 兼容。使用 MinIO 为机器学习、分析和应用程序数据工作负载构建高性能基础架构。MinIO是高性能对象存储,什么是对象存储(Object Storage Service),对象存储是支持海量用户远程访问的无限容量廉价存储系统,既然是存储系统。
什么是MinIO?
MinIO 是在 GNU Affero 通用公共许可证 v3.0 下发布的高性能对象存储。它与 Amazon S3 云存储服务 API 兼容。使用 MinIO 为机器学习、分析和应用程序数据工作负载构建高性能基础架构。
MinIO是高性能对象存储,什么是对象存储(Object Storage Service),对象存储是支持海量用户远程访问的无限容量廉价存储系统,既然是存储系统。
它由桶(bucket,对应Windows下的文件夹),组成目录结构,桶中直接存放对象(Object,对应Windwos下的文件),桶中不能再创建通,但是要能创建文件夹。
怎么用?
下载MinIO
访问官网:https://docs.min.io/
进入下载页面点击windows
点击下载服务端
将MinIO.exe 拷贝到自己的目录下去,并创建一个data目录
通过命令行启动Minio
minio server ./data
启动完成后,可以看到访问的路径http://127.0.0.1:9000
使用提供的账号密码进行登录
账号:minioadmin
密码:minioadmin
说明minio已经正常启动了
MioIO的使用
由于我们已经了解到MinIO是由桶(bucket)组成的,相当于是文件夹
对应的应该先要创建通bucket
创建桶
创建名叫huike-crm的桶
创建好桶之后看到如下内容
先尝试通过MinIO的控制台上传一个文件
上传一个java.png
点击上传的文件并生成分享的链接
点击copy拷贝生成分享的url
http://172.16.17.121:9000/huike-crm/java.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=KGWTGVTCK8G5MV01HQ5A%2F20220318%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220318T081644Z&X-Amz-Expires=604800&X-Amz-Security-Token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJLR1dUR1ZUQ0s4RzVNVjAxSFE1QSIsImV4cCI6MTY0NzU5MzU4MSwicGFyZW50IjoibWluaW9hZG1pbiJ9.BdsOeJp6v1zPUPTH79Eb4u_Mf_f8eG0Pvwd8IewMdI1mJGSzqYnJxaP3SKV_-c4AtoIYBJBT_4zh2N3AYYFOUw&X-Amz-SignedHeaders=host&versionId=null&X-Amz-Signature=c3205a0361341505aa4107655716c4e71a47dd40606bd4e03033138fbd6b7c96
在浏览器里访问,可以看到上传的图片
可以看到图片里的内容,证明minio已经可以正常使用了
但是,存在一些问题,我们生成一个分享url的时候发现有一个有效期
也就是说我们生成的分享的url的有效期只有7天,过了这7天以后再想通过这个url来进行访问就会有问题
我们能否直接将上传上来的文件暴露出去,而不再需要通过分享的这个url来进行访问呢?
如果现在我们要直接访问我们的MinIO里的文件要如何访问
我们应该直接访问 Minio的ip+端口/桶名称/文件名
http://172.16.17.121:9000/huike-crm/java.png
我们在浏览器中尝试了一下
看到返回的数据的内容,没有权限
注意这里的权限的配置是在桶这一级别的
添加读取readOnly对应的权限是*即拥有所有权限
然后重新范围java.png
http://172.16.17.121:9000/huike-crm/java.png
到此对minio的配置全部结束
现在与java集成
参考官网
导入maven
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.3.7</version>
</dependency>
FileUploader.java
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.UploadObjectArgs;
import io.minio.errors.MinioException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class FileUploader {
public static void main(String[] args)
throws IOException, NoSuchAlgorithmException, InvalidKeyException {
try {
// Create a minioClient with the MinIO server playground, its access key and secret key.
MinioClient minioClient =
MinioClient.builder()
.endpoint("https://play.min.io")
.credentials("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG")
.build();
// Make 'asiatrip' bucket if not exist.
boolean found =
minioClient.bucketExists(BucketExistsArgs.builder().bucket("asiatrip").build());
if (!found) {
// Make a new bucket called 'asiatrip'.
minioClient.makeBucket(MakeBucketArgs.builder().bucket("asiatrip").build());
} else {
System.out.println("Bucket 'asiatrip' already exists.");
}
// Upload '/home/user/Photos/asiaphotos.zip' as object name 'asiaphotos-2015.zip' to bucket
// 'asiatrip'.
minioClient.uploadObject(
UploadObjectArgs.builder()
.bucket("asiatrip")
.object("asiaphotos-2015.zip")
.filename("/home/user/Photos/asiaphotos.zip")
.build());
System.out.println(
"'/home/user/Photos/asiaphotos.zip' is successfully uploaded as "
+ "object 'asiaphotos-2015.zip' to bucket 'asiatrip'.");
} catch (MinioException e) {
System.out.println("Error occurred: " + e);
System.out.println("HTTP trace: " + e.httpTrace());
}
}
}
具体实现:
文件上传实现类:
@Service
@Slf4j
public class SysFileServiceImpl implements ISysFileService{
@Autowired
MinioConfig minioConfig;
/**
* 文件上传至Minio
* 使用try catch finally进行上传
* finally里进行资源的回收
*/
@Override
public AjaxResult upload(MultipartFile file) {
InputStream inputStream = null;
//创建Minio的连接对象
MinioClient minioClient = getClient();
String bucketName = minioConfig.getBucketName();
try {
inputStream = file.getInputStream();
//判断文件存储的桶是否存在 如果桶不存在就创建桶
isBucket(minioClient, bucketName);
//操作文件(构建文件目录:2024/02/22/550e8400e29b41d4a716446655440000example.pdf)
String fileName = file.getOriginalFilename();
String fileNameFinal = new SimpleDateFormat("yyyy/MM/dd/").format(new Date()) //获取当前日期格式化为路径格式
+ UUID.randomUUID().toString().replaceAll("-", "") //去掉UUID生成的字符串中的 -
+ fileName.substring(fileName.lastIndexOf(".")); //拼接原文件的后缀 .pgf
//文件上传
//由于使用的是SpringBoot与之进行集成 上传的时候拿到的是MultipartFile 需要通过输入输出流的方式进行添加
PutObjectArgs objectArgs = PutObjectArgs.builder()
.object(fileNameFinal)
.bucket(bucketName)
.contentType(file.getContentType())
.stream(file.getInputStream(), file.getSize(), -1)
.build();
minioClient.putObject(objectArgs);
//封装访问的url给前端
AjaxResult ajax = AjaxResult.success();
ajax.put("fileName","/" + bucketName + "/" + fileNameFinal);
//拼接url
ajax.put("url",minioConfig.getEndpoint() + ":" + minioConfig.getPort() + "/" + minioConfig.getBucketName() + "/" + fileNameFinal);
return ajax;
}catch(Exception e){
e.printStackTrace();
return AjaxResult.error("上传失败");
}finally {
//防止内存泄漏
if (inputStream != null) {
try {
inputStream.close(); // 关闭流
} catch (IOException e) {
log.debug("inputStream close IOException:" + e.getMessage());
}
}
}
}
/**
* 判断桶是否存在,不存在则创建
* @param minioClient
* @param bucketName
* @throws ErrorResponseException
* @throws InsufficientDataException
* @throws InternalException
* @throws InvalidKeyException
* @throws InvalidResponseException
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws ServerException
* @throws XmlParserException
*/
private static void isBucket(MinioClient minioClient, String bucketName) throws ErrorResponseException, InsufficientDataException, InternalException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException {
boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
if (!found){
//如果桶不存在,则创建桶
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
}
/**
* 免费提供一个获取Minio连接的方法
* 获取Minio连接
* @return
*/
private MinioClient getClient(){
MinioClient minioClient =
MinioClient.builder()
.endpoint("http://"+minioConfig.getEndpoint()+":"+ minioConfig.getPort())
.credentials(minioConfig.getAccessKey(),minioConfig.getSecretKey())
.build();
return minioClient;
}
}
文件上传配置类:
@Data
@Component
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
private final static String HTTP = "http://";
//endPoint是一个URL,域名,IPv4或者IPv6地址
private String endpoint;
//TCP/IP端口号
private int port;
//accessKey类似于用户ID,用于唯一标识你的账户
private String accessKey;
//secretKey是你账户的密码
private String secretKey;
//如果是true,则用的是https而不是http,默认值是true
private Boolean secure;
//默认存储桶
private String bucketName;
}
配置文件:
# Miniio配置
minio:
endpoint: 127.0.0.1
port: 9000
accessKey: minioadmin
secretKey: minioadmin
secure: false
bucketName: "huike-crm"
configDir: "/data/excel"
更多推荐
所有评论(0)