SpringBoot整合minio分布式文件实操
1.写在前面
在java web编程中,目前微服务体系的框架越来越流行了,随着服务的拆分,可能我们的项目的细粒度,会变得很细。
一般的项目,基本上都会涉及到文件的存储。对于文件的存储,这个在微服务的体系下,我们可以将文件抽取出一个独立的文件微服务。然后提供相应的api(上传,下载,删除)等......
对于独立的文件微服务,我们可以根据项目的需求,使用策略模式,整合多个文件服务器,例如:阿里云Oss
、fastdfs
、minio
等。
今天我们主要讲的是minio
:
MinIO是专门为海量数据存储、人工智能、大数据分析而设计的对象存储系统。据官方介绍,单个对象最大可达5TB。非常适合储海量图片、视频、日志文件、备份数据和容器/虚拟机镜像等
- 安装部署非常简单
- 操作简单,自带ui
- 性能优秀,可以达到每秒GB级别的读写速度
- 支持主流的云原生容器化部署
- 提供多语言SDK的支持
- 参考学习文档非常全面
既然minio有这么多优点,那我们来整合一下minio吧!
2.minio部署
学习文档:minio学习文档
githug地址:minio
java sdk文档:java sdk
docker 部署文档:docker部署minio
这里提供的文档是英文的,为什么这里列出中文的文档呢?
那是因为中文的文档,有些地址都是404,好像没有更新维护一样,所以这里只是列出英文的文档。
但是也建议大家看英文的文档,毕竟大部分的文档都是英文的。哈哈!!!
这里使用docker方式部署minio:
# 创建一个文件夹
mkdir -p ~/minio/data
# docker运行minio
docker run \
-p 9000:9000 \
-p 9090:9090 \
--name minio \
-v ~/minio/data:/data \
-e "MINIO_ROOT_USER=ROOTNAME" \
-e "MINIO_ROOT_PASSWORD=CHANGEME123" \
quay.io/minio/minio server /data --console-address ":9090"
当前镜像版本:RELEASE.2022-08-26T19-53-15Z
上面的命令,有过docker基础的人应该都可以看得懂吧,没有的也没关系,我们一一说明一下:
-p:9000:9000 (hostPort:containerPort)表示映射的容器的9000端口到主机的9000端号。
--name minio 表示给当前容器一个名称为minio
-v ~/minio/data:/data 表示将容器的/data文件夹,挂载到主机的~/minio/data文件夹下面
-e "MINIO_ROOT_USER=ROOTNAME" 表示传递一个环境变量给到容器。
quay.io/minio/minio 表示镜像名称
server /data --console-address ":9090" 表示容器启动后需要执行的命令
MINIO_ROOT_USER、MINIO_ROOT_PASSWORD,为minio的账号密码,可以用来登录web ui客户端,也可以作为java sdk的accessKey、secretKey
--console-address ":9090",为web ui客户端的端口号
-p 9000:9000,为minio api的端口号
minio启动成功后,可以直接访问:http://localhost:9090 进入到web ui客户端
3.整合minio
3.1 pom.xml依赖
<!--加入minio的依赖-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.4.1</version>
<exclusions>
<exclusion>
<artifactId>okhttp</artifactId>
<groupId>com.squareup.okhttp3</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
3.2 minio 配置
{
"endpoint": "http://localhost:9000",
"bucketName": "llsydn",
"accessKey": "ROOTNAME",
"secretKey": "CHANGEME123"
}
endpoint,就是minio api的ip+端口号,就是上面暴露的9000端口
accessKey,secretKey,就是上面的MINIO_ROOT_USER和MINIO_ROOT_PASSWORD
bucketName,表示桶名,我们可以理解为一个文件夹名称
3.3 minio客户端
/**
* 构造minio客户端。
*
* @param sysFileStore
* @return
*/
private MinioClient buildMinioClient(JSONObject sysFileStore) {
//连接地址
String endpoint = sysFileStore.getString("endpoint");
//账号
String accessKey = sysFileStore.getString("accessKey");
//密码
String secretKey = sysFileStore.getString("secretKey");
MinioClient minioClient = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
return minioClient;
}
3.4 上传文件
@Override
public boolean createFile(String fileName, byte[] bytes) {
try {
String config = "刚才那段json配置";
JSONObject sysFileStore = JSONObject.parseObject(config);
String bucketName = sysFileStore.getString("bucketName");
// 创建MinioClient实例
MinioClient minioClient = buildMinioClient(sysFileStore);
// 先判断bucketName桶是否存在,不存在,先创建桶
BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucketName).build();
boolean flag = minioClient.bucketExists(bucketExistsArgs);
if (!flag) {
MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();
minioClient.makeBucket(makeBucketArgs);
}
//fileName:存储桶里的对象名称
PutObjectArgs putObjectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName)
.stream(new ByteArrayInputStream(bytes), bytes.length, -1).build();
// 上传到minio
minioClient.putObject(putObjectArgs);
} catch (Exception e) {
log.error("------MinioOperator.createFile is error :" + e.getMessage());
}
}
3.5 下载文件
@Override
public void downFile(HttpServletResponse response, String path) {
try {
String config = "刚才那段json配置";
JSONObject sysFileStore = JSONObject.parseObject(config);
String bucketName = sysFileStore.getString("bucketName");
// 创建minioClient实例。
MinioClient minioClient = buildMinioClient(sysFileStore);
//sysFile.getPath():存储桶里的对象名称
GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName).object(path).build();
// 获取minio文件inputStream对象
InputStream inputStream = minioClient.getObject(objectArgs);
FileUtil.downLoad(inputStream, response);
} catch (Exception e) {
log.error("------MinioOperator.downFile is error :" + e.getMessage());
}
}
3.6 删除文件
@Override
public int delFile(String path) {
try {
String config = "刚才那段json配置";
JSONObject sysFileStore = JSONObject.parseObject(config);
//存储桶名称
String bucketName = sysFileStore.getString("bucketName");
// 创建minioClient实例。
MinioClient minioClient = buildMinioClient(sysFileStore);
//path:存储桶里的对象名称
minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(path).build());
} catch (Exception ex) {
log.error("------MinioOperator.delFile is error :" + e.getMessage());
}
return 0;
}
好了,以上就是SpringBoot整合minio分布式文件实操的分享了。
可能内容有点短,但都是干货喔!!!
个人理解,可能也不够全面,班门弄斧了。
如果觉得有收获的,帮忙点赞、评论、收藏
一下呗!!!
转载自:https://juejin.cn/post/7137483077764251679