你可需要的对象存储中间件《Minio使用》
Posted 香菜+
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你可需要的对象存储中间件《Minio使用》相关的知识,希望对你有一定的参考价值。
最近的项目中因为需要做一些上传和下载的工作,所以选择了minio。当然这也是公司的选择,废话不多说,今天主要是记录下经验。
1、minio相关信息
1.1 官方信息
中文网站:MinIO | 高性能,对Kubernetes友好的对象存储
你懂得,去掉cn 就是官方网站。在官方网站上有你要的信息。不打开看看吗?看起来了不起的样子
MinIO 是一款高性能、分布式的对象存储系统. 它是一款软件产品, 可以100%的运行在标准硬件。即X86等低成本机器也能够很好的运行MinIO。
MinIO与传统的存储和其他的对象存储不同的是:它一开始就针对性能要求更高的私有云标准进行软件架构设计。因为MinIO一开始就只为对象存储而设计。所以他采用了更易用的方式进行设计,它能实现对象存储所需要的全部功能,在性能上也更加强劲,它不会为了更多的业务功能而妥协,失去MinIO的易用性、高效性。 这样的结果所带来的好处是:它能够更简单的实现局有弹性伸缩能力的原生对象存储服务。
MinIO在传统对象存储用例(例如辅助存储,灾难恢复和归档)方面表现出色。同时,它在机器学习、大数据、私有云、混合云等方面的存储技术上也独树一帜。当然,也不排除数据分析、高性能应用负载、原生云的支持。
在中国:阿里巴巴、腾讯、百度、中国联通、华为、中国移动等等9000多家企业也都在使用MinIO产品
1.2 MinIO优势
1、数据安全
分布式存储,保证数据安全
2、高可用
分布式多副本机制,可以保证服务的高可用,即使挂掉几个也能保证服务
3、一致性
1.3 应用场景
互联网非结构化数据的存储需求
- 电商网站:海量商品图片
- 视频网站:海量视频文件
- 网盘:海量文件
2、部署
懒省事,直接选择docker部署,看下脚本吧,没啥问题。
docker run -p 9000:9000 --net=host \\
--name minio1 \\
-d \\
-e MINIO_ACCESS_KEY=minio \\
-e MINIO_SECRET_KEY=minio@123 \\
-v /home/docker/minio/data:/data \\
-v /home/docker/minio/config:/root/.minio \\
minio/minio server /data
启动起来登录进控制台
管理地址:http://172.26.1.152:9000/,用户名和地址在上面的脚本里
3、Springboo继承Minio
1、添加依赖
这里在线上直接找了一个,你可以在repo里查找最新的
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.0.0</version>
</dependency>
2、配置文件
application.yml,这里直接创建了一个配置,你可以根据自己的需求定义格式
minio:
endpoint: http://172.26.1.152:9000 # endpoint
accessKey: minio #用户名
secretKey: minio@123 # 密码
bucketName: apply # bucketName
3、读取配置文件
这里使用了lombok,如果你没使用的话,可以去除data注解,然后创建一些get/set方法。
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 endpoint;
private String accessKey;
private String secretKey;
@Bean
public MinioClient minioClient()
MinioClient minioClient = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
return minioClient;
4、创建一个工具类
这里借鉴了一些线上的文档,然后加了一些修改,可以直接拷贝到项目中使用。
package com.xin.miniodemo.config;
import io.minio.*;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* minio 工具类
*/
@Component
@Slf4j
public class MinioUtil
@Autowired
private MinioClient minioClient;
/**
* 查看存储bucket是否存在
*
* @return boolean
*/
public boolean bucketExists(String bucketName)
boolean found = false;
try
BucketExistsArgs args = BucketExistsArgs.builder().bucket(bucketName)
.build();
found = minioClient.bucketExists(args);
catch (Exception e)
log.error("bucketExists ", e);
return found;
/**
* 创建存储bucket
*
* @return Boolean
*/
public boolean makeBucket(String bucketName)
try
MakeBucketArgs makeArgs = MakeBucketArgs.builder()
.bucket(bucketName)
.build();
minioClient.makeBucket(makeArgs);
catch (Exception e)
log.error("makeBucket ", e);
return false;
return true;
/**
* 删除存储bucket
*
* @return Boolean
*/
public boolean removeBucket(String bucketName)
try
RemoveBucketArgs removeArgs = RemoveBucketArgs.builder()
.bucket(bucketName)
.build();
minioClient.removeBucket(removeArgs);
catch (Exception e)
log.error("removeBucket ", e);
return false;
return true;
/**
* 获取全部bucket
*/
public List<Bucket> getAllBuckets()
try
return minioClient.listBuckets();
catch (Exception e)
log.error("getAllBuckets ", e);
return null;
/**
* 文件上传
*
* @param bucketName
* @param fileName 上传文件的路径和名字
* @param file
* @return
*/
public boolean upload(String bucketName, String fileName, MultipartFile file)
try
PutObjectArgs objectArgs = PutObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.stream(file.getInputStream(), file.getSize(), -1)
.contentType(file.getContentType())
.build();
//文件名称相同会覆盖
minioClient.putObject(objectArgs);
catch (Exception e)
log.error("upload ", e);
return false;
return true;
/**
* 文件下载
*
* @param fileName 文件的路径和名字
* @return Boolean
*/
public void download(String fileName, String saveName, String bucketName)
DownloadObjectArgs build = DownloadObjectArgs.builder()
.bucket(bucketName)
.filename(saveName)
.object(fileName)
.build();
try
minioClient.downloadObject(build);
catch (Exception e)
throw new RuntimeException(e);
/**
* web下载文件
*
* @param fileName 文件的路径和名字
* @param bucketName
* @param resp
*/
public void webDownload(String fileName, String bucketName, HttpServletResponse resp)
GetObjectArgs objectArgs = GetObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.build();
try (GetObjectResponse response = minioClient.getObject(objectArgs))
byte[] buf = new byte[1024];
int len;
try (FastByteArrayOutputStream os = new FastByteArrayOutputStream())
while ((len = response.read(buf)) != -1)
os.write(buf, 0, len);
os.flush();
byte[] bytes = os.toByteArray();
resp.setCharacterEncoding("utf-8");
//设置强制下载不打开
//res.setContentType("application/force-download");
resp.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
try (ServletOutputStream stream = resp.getOutputStream())
stream.write(bytes);
stream.flush();
catch (Exception e)
log.error("webDownload ", e);
/**
* 查看文件对象
*
* @return 存储bucket内文件对象信息
*/
public List<Item> listObjects(String bucketName)
ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder()
.bucket(bucketName)
.build();
Iterable<Result<Item>> results = minioClient.listObjects(listObjectsArgs);
List<Item> itemList = new ArrayList<>();
try
for (Result<Item> result : results)
itemList.add(result.get());
catch (Exception e)
log.error("listObjects ", e);
return null;
return itemList;
/**
* 删除
*
* @param fileName
* @return
* @throws Exception
*/
public boolean removeOne(String fileName, String bucketName)
try
RemoveObjectArgs removeArgs = RemoveObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.build();
minioClient.removeObject(removeArgs);
catch (Exception e)
log.error("remove ", e);
return false;
return true;
/**
* 批量删除文件对象
*
* @param objects 对象名称集合
*/
public Iterable<Result<DeleteError>> removeObjects(List<String> objects, String bucketName)
List<DeleteObject> dos = objects.stream().map(DeleteObject::new).collect(Collectors.toList());
RemoveObjectsArgs build = RemoveObjectsArgs.builder()
.bucket(bucketName)
.objects(dos)
.build();
Iterable<Result<DeleteError>> results = minioClient.removeObjects(build);
return results;
5、测试代码,
这里直接创建了一个controller测试
import com.xin.miniodemo.config.MinioUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
@RestController
@RequestMapping
public class TestController
@Autowired
private MinioUtil minioUtil;
@PostMapping("/upload")
public String test(MultipartFile file)
minioUtil.upload("chongxin",file.getOriginalFilename(),file);
return "Hello";
@PostMapping("/delete")
public String delete(String fileName)
String[] fileArr = fileName.split(",");
List<String> fl = Arrays.asList(fileArr);
minioUtil.removeObjects(fl,"chongxin");
return "Hello";
@PostMapping("/download")
public String download(String fileName)
minioUtil.download(fileName,"chongxin.jpg","chongxin.jpg");
return "Hello";
@PostMapping("/webdownload")
public String download(String fileName, HttpServletResponse response)
minioUtil.webDownload(fileName,"chongxin",response);
return "Hello";
4、总结
在开发的过程中还是出现一些问题的,但是已经都解决了,没有及时记录问题,这个有点可惜。
撸代码的时间还是快乐的,特别是解决问题之后,很开心
你的点赞是我分享的动力,欢迎点赞评论分享
以上是关于你可需要的对象存储中间件《Minio使用》的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot2 整合MinIO中间件,实现文件便捷管理
分布式技术专题「OSS中间件系列」从0到1的介绍一下开源对象存储MinIO技术架构
分布式技术专题「OSS中间件系列」从0到1的介绍一下开源对象存储MinIO技术架构
#私藏项目实操分享#分布式技术专题「OSS中间件系列」Minio的Server端服务的架构和实战搭建