简要说明
最近在重构毕业设计,但是阿里云oss对接的服务器没有续费所以oss回调不能用,然后就找了另外的一个oss对象存储来代替阿里云的oss。
MinIO 是一款高性能、分布式的对象存储系统. 它是一款软件产品, 可以100%的运行在标准硬件。即X86等低成本机器也能够很好的运行MinIO。
MinIO与传统的存储和其他的对象存储不同的是:它一开始就针对性能要求更高的私有云标准进行软件架构设计。因为MinIO一开始就只为对象存储而设计。所以他采用了更易用的方式进行设计,它能实现对象存储所需要的全部功能,在性能上也更加强劲,它不会为了更多的业务功能而妥协,失去MinIO的易用性、高效性。 这样的结果所带来的好处是:它能够更简单的实现局有弹性伸缩能力的原生对象存储服务。
MinIO在传统对象存储用例(例如辅助存储,灾难恢复和归档)方面表现出色。同时,它在机器学习、大数据、私有云、混合云等方面的存储技术上也独树一帜。当然,也不排除数据分析、高性能应用负载、原生云的支持。
在中国:阿里巴巴、腾讯、百度、中国联通、华为、中国移动等等9000多家企业也都在使用MinIO产品。
以上是引用自官网的一段概述,MinIo官方网站
搭建
笔者是基于docker进行服务搭建的,执行以下命令即可完成搭建。
docker pull minio/minio
docker run --name myminio -p 8789:9000 -itd
--restart=always
-v /etc/localtime:/etc/localtime
-v /home/mycontainers/myminio/data:/data
-v /home/mycontainers/myminio/config:/root/.minio --net mynetwork
-e "MINIO_ACCESS_KEY=minio"
-e "MINIO_SECRET_KEY=minio123"
minio/minio:RELEASE.2021-06-17T00-10-46Z server /data
第一步:拉取MinIo镜像
第二步:docker启动minio容器
参数说明:
--restart:是否随着docker服务启动而启动
-v:将宿主机的目录挂载到容器里面,格式--》宿主机目录:容器内目录
-e:环境,此处指定了使用者的ACCESS_KEY和SECRET_KEY
启动成功后,访问你对应的IP和端口即可,如下图
此UI界面非常的简洁。输入上面的key进入内部,如下图:
左边的是桶的名字,右边的文件是当前桶的对象文件,右下角是创建桶
依赖
基于传统Spring Boot架构的基础上仅仅添加一些以下依赖即可。
<!-- https://mvnrepository.com/artifact/io.minio/minio -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.0.3</version>
</dependency>
基础配置
@Configuration
public class minioConfig {
@Value("${minio.endpoint}")
private String endpoint;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;
@Bean
public MinioClient minioClient(){
return MinioClient.builder().endpoint(endpoint).credentials(accessKey,secretKey).build();
}
}
基础接口
1. 验证桶是否存在
@Test
void bucketExists() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(minioFinal.bucketName).build();
System.out.println(minioClient.bucketExists(bucketExistsArgs));
}
2. 创建桶
@Test
void MakeBucketArgs() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
/**
* 桶名字不能有大写
*/
MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket("testbucket").build();
minioClient.makeBucket(makeBucketArgs);
}
ps:桶的名字不能大写,笔者尝试过驼峰命名,api会报异常,或者可以尝试一下在图型界面创建桶包含大写字母也会报错。
3. 列出所有的桶
@Test
void BucketList() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
List<Bucket> list = minioClient.listBuckets();
for (Bucket bucket : list) {
System.out.println(bucket.name());
}
}
4. 删除桶
@Test
void removeBucket() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
//必须桶为空才能删
RemoveBucketArgs removeBucketArgs = RemoveBucketArgs.builder().bucket("temp").build();
minioClient.removeBucket(removeBucketArgs);
}
5. 列出某个存储桶中的所有对象
@Test
void listObjects() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder().bucket(minioFinal.bucketName).build();
Iterable<Result<Item>> list = minioClient.listObjects(listObjectsArgs);
for (Result<Item> result : list) {
//获取到对象
Item item = result.get();
System.out.println(item.objectName());
System.out.println(item.size());
}
}
6. 获取到对象
@Test
void getObject() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
GetObjectArgs getObjectArgs = GetObjectArgs.builder().bucket(minioFinal.bucketName).object("新建文本文档.txt").build();
InputStream stream = minioClient.getObject(getObjectArgs);
// 读取输入流直到EOF并打印到控制台。
byte[] buf = new byte[16384];
int bytesRead;
while ((bytesRead = stream.read(buf, 0, buf.length)) >= 0) {
System.out.println(new String(buf, 0, bytesRead));
}
// 关闭流。
stream.close();
}
7. 下载对象
@Test
void downloadObject() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
DownloadObjectArgs downloadObjectArgs = DownloadObjectArgs.builder().bucket(minioFinal.bucketName).object("86231487_p0.jpg")
.filename("D:\\86231487_p0.jpg").build();
minioClient.downloadObject(downloadObjectArgs);
}
8. 上传对象
@PostMapping("/upload")
public String upload(List<MultipartFile> file){
try {
for (MultipartFile f :file) {
PutObjectArgs objectArgs = PutObjectArgs.builder().object(f.getOriginalFilename())
.bucket(minioFinal.bucketName)
.contentType(f.getContentType())
.stream(f.getInputStream(),f.getSize(),-1).build();
minioClient.putObject(objectArgs);
}
return "ok";
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
}
}
9. 复杂桶对象
@Test
void copyObject() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
CopyObjectArgs copyObjectArgs = CopyObjectArgs.builder()
//目标桶名
.bucket(minioFinal.bucketName2)
//目标对象名
.object("justic2353.jpg")
.source(
CopySource.builder()
//源桶名
.bucket(minioFinal.bucketName)
//源目标名称
.object("justic.jpg")
.build()
).build();
minioClient.copyObject(copyObjectArgs);
}
10. 删除对象
@Test
void removeObject() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(minioFinal.bucketName2).object("justic2353.jpg").build();
minioClient.removeObject(removeObjectArgs);
}
11. 批量删除对象
@Test
void removeObjects() throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
List<DeleteObject> list = new ArrayList<>();
list.add(new DeleteObject("006ywv2aly1h0x03vp341j31ww2pg7wh.jpg"));
list.add(new DeleteObject("nacos_config_export_20220707215727.zip"));
RemoveObjectsArgs removeObjectArgs = RemoveObjectsArgs.builder()
.bucket(minioFinal.bucketName2)
.objects(list).build();
Iterable<Result<DeleteError> > results = minioClient.removeObjects(removeObjectArgs);
System.out.println(results.iterator());
for (Result<DeleteError> result : results) {
System.out.println(result);
DeleteError error = result.get();
System.out.println(
"Error in deleting object " + error.objectName() + "; " + error.message());
}
}