MinIO的入门使用方法
1. MinIO简介
MinIO基于Apache License v2.0开源协议的对象存储服务,可以做为云存储的解决方案用来保存海量的图片,视频,文档。由于采用Golang实现,服务端可以工作在Windows,Linux, OS X和FreeBSD上。配置简单,基本是复制可执行程序,单行命令可以运行起来。
MinIO兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。
S3 ( Simple Storage Service简单存储服务)
基本概念
- bucket – 类比于文件系统的目录
- Object – 类比文件系统的文件
- Keys – 类比文件名
官网文档:http://docs.minio.org.cn/docs/
MinIO特点
数据保护
Minio使用Minio Erasure Code(纠删码)来防止硬件故障。即便损坏一半以上的driver,但是仍然可以从中恢复。
高性能
作为高性能对象存储,在标准硬件条件下它能达到55GB/s的读、35GB/s的写速率
可扩容
不同MinIO集群可以组成联邦,并形成一个全局的命名空间,并跨越多个数据中心
SDK支持
基于Minio轻量的特点,它得到类似Java、Python或Go等语言的sdk支持
有操作页面
面向用户友好的简单操作界面,非常方便的管理Bucket及里面的文件资源
功能简单
这一设计原则让MinIO不容易出错、更快启动
丰富的API
支持文件资源的分享连接及分享链接的过期策略、存储桶操作、文件列表访问及文件上传下载的基本功能等。
文件变化主动通知
存储桶(Bucket)如果发生改变,比如上传对象和删除对象,可以使用存储桶事件通知机制进行监控,并通过以下方式发布出去:AMQP、MQTT、Elasticsearch、Redis、NATS、MySQL、Kafka、Webhooks等。
2.快速入门
2.1.安装&启动&管理
这里直接在宝塔面板安装,十分快捷方便,安装后也可以在面板中直接管理
开放端口 9000 和 9001
访问http://47.113.202.66:9001/
初始用户密码可以在宝塔面板中看到
这里需要新建一个Bucket,以供后面导入使用
2.2.导入依赖
这里新建了一个测试的模块,所以需要导入以下模块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <dependencies> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>7.1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> </dependencies>
|
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| import io.minio.MinioClient; import io.minio.PutObjectArgs; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;
import java.io.FileInputStream;
@SpringBootTest public class MinIOTest {
@Test public void testMinIO() throws Exception { FileInputStream fileInputStream = null; try {
fileInputStream = new FileInputStream("E:\\test.html");;
MinioClient minioClient = MinioClient.builder() .credentials("admin", "admin@pwd") .endpoint("http://47.113.202.66:9000") .build(); PutObjectArgs putObjectArgs = PutObjectArgs.builder() .object("test.html") .contentType("text/html") .bucket("heimatoutiao") .stream(fileInputStream, fileInputStream.available(), -1) .build(); minioClient.putObject(putObjectArgs);
System.out.println("http://47.113.202.66:9000/heimatoutiao/test.html");
} catch (Exception ex) { ex.printStackTrace(); }
} }
|
2.3.运行结果
在minio管理页面中可以看到成功导入了,点击链接也可以直接访问
3.封装为Starter
3.1 创建模块heima-file-starter
导入依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>7.1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies>
|
3.2配置类
MinIOConfigProperties
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.heima.file.config;
import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties;
import java.io.Serializable;
@Data @ConfigurationProperties(prefix = "minio") public class MinIOConfigProperties implements Serializable {
private String accessKey; private String secretKey; private String bucket; private String endpoint; private String readPath; }
|
MinIOConfig
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package com.heima.file.config;
import com.heima.file.service.FileStorageService; import io.minio.MinioClient; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Data @Configuration @EnableConfigurationProperties({MinIOConfigProperties.class})
@ConditionalOnClass(FileStorageService.class) public class MinIOConfig {
@Autowired private MinIOConfigProperties minIOConfigProperties;
@Bean public MinioClient buildMinioClient(){ return MinioClient .builder() .credentials( minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey() ) .endpoint(minIOConfigProperties.getEndpoint()) .build(); } }
|
3.2 封装操作minIO类
FileStorageService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| package com.heima.file.service;
import java.io.InputStream;
public interface FileStorageService {
public String uploadImgFile(String prefix, String filename, InputStream inputStream);
public String uploadHtmlFile(String prefix, String filename, InputStream inputStream);
public void delete(String pathUrl);
public byte[] downLoadFile(String pathUrl);
}
|
MinIOFileStorageService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
| package com.heima.file.service.impl;
import com.heima.file.config.MinIOConfig; import com.heima.file.config.MinIOConfigProperties; import com.heima.file.service.FileStorageService; import io.minio.GetObjectArgs; import io.minio.MinioClient; import io.minio.PutObjectArgs; import io.minio.RemoveObjectArgs; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Import; import org.springframework.util.StringUtils;
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date;
@Slf4j @EnableConfigurationProperties(MinIOConfigProperties.class) @Import(MinIOConfig.class) public class MinIOFileStorageService implements FileStorageService {
@Autowired private MinioClient minioClient;
@Autowired private MinIOConfigProperties minIOConfigProperties;
private final static String separator = "/";
public String builderFilePath(String dirPath,String filename) { StringBuilder stringBuilder = new StringBuilder(50); if(!StringUtils.isEmpty(dirPath)){ stringBuilder.append(dirPath).append(separator); } SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); String todayStr = sdf.format(new Date()); stringBuilder.append(todayStr).append(separator); stringBuilder.append(filename); return stringBuilder.toString(); }
@Override public String uploadImgFile(String prefix, String filename, InputStream inputStream) { String filePath = builderFilePath(prefix, filename); try { PutObjectArgs putObjectArgs = PutObjectArgs.builder() .object(filePath) .contentType("image/jpg") .bucket(minIOConfigProperties.getBucket()) .stream(inputStream,inputStream.available(),-1) .build(); minioClient.putObject(putObjectArgs); StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath()); urlPath.append(separator+minIOConfigProperties.getBucket()); urlPath.append(separator); urlPath.append(filePath); return urlPath.toString(); }catch (Exception ex){ log.error("minio put file error.",ex); throw new RuntimeException("上传文件失败"); } }
@Override public String uploadHtmlFile(String prefix, String filename, InputStream inputStream) { String filePath = builderFilePath(prefix, filename); try { PutObjectArgs putObjectArgs = PutObjectArgs.builder() .object(filePath) .contentType("text/html") .bucket(minIOConfigProperties.getBucket()) .stream(inputStream,inputStream.available(),-1) .build(); minioClient.putObject(putObjectArgs); StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath()); urlPath.append(separator+minIOConfigProperties.getBucket()); urlPath.append(separator); urlPath.append(filePath); return urlPath.toString(); }catch (Exception ex){ log.error("minio put file error.",ex); ex.printStackTrace(); throw new RuntimeException("上传文件失败"); } }
@Override public void delete(String pathUrl) { String key = pathUrl.replace(minIOConfigProperties.getEndpoint()+"/",""); int index = key.indexOf(separator); String bucket = key.substring(0,index); String filePath = key.substring(index+1); RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder() .bucket(bucket).object(filePath).build(); try { minioClient.removeObject(removeObjectArgs); } catch (Exception e) { log.error("minio remove file error. pathUrl:{}",pathUrl); e.printStackTrace(); } }
@Override public byte[] downLoadFile(String pathUrl) { String key = pathUrl.replace(minIOConfigProperties.getEndpoint()+"/",""); int index = key.indexOf(separator); String bucket = key.substring(0,index); String filePath = key.substring(index+1); InputStream inputStream = null; try { inputStream = minioClient.getObject( GetObjectArgs.builder() .bucket(minIOConfigProperties.getBucket()) .object(filePath) .build() ); } catch (Exception e) { log.error("minio down file error. pathUrl:{}",pathUrl); e.printStackTrace(); }
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buff = new byte[100]; int rc = 0; while (true) { try { if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break; } catch (IOException e) { e.printStackTrace(); } byteArrayOutputStream.write(buff, 0, rc); } return byteArrayOutputStream.toByteArray(); } }
|
3.3 对外加入自动配置
在resources中新建META-INF/spring.factories
1 2
| org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.heima.file.service.impl.MinIOFileStorageService
|
3.4 其他微服务使用
第一,导入heima-file-starter的依赖
第二,在微服务中添加minio所需要的配置
1 2 3 4 5 6
| minio: accessKey: xxx secretKey: xxx bucket: buckernamexxx endpoint: http://47.113.202.66:9000 readPath: http://47.113.202.66:9000
|
第三,在对应使用的业务类中注入FileStorageService,样例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package com.heima.minio.test;
import com.heima.file.service.FileStorageService; import com.heima.minio.MinioApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;
import java.io.FileInputStream; import java.io.FileNotFoundException;
@SpringBootTest(classes = MinioApplication.class) @RunWith(SpringRunner.class) public class MinioTest { @Autowired private FileStorageService fileStorageService;
@Test public void testMinIO() throws Exception { FileInputStream fileInputStream = new FileInputStream("E:\\test.html"); String path = fileStorageService.uploadHtmlFile("", "test.html", fileInputStream); System.out.println(path); } }
|
4.封装为工具类
参考:springboot整合minio_springboot整合miniocsdn-CSDN博客