赞
踩
官网地址:https://minio.org.cn
MinIO是一款基于Apache License v2.0开源协议的分布式文件系统(或者叫对象存储服务),可以做为云存储的解决方案用来保存海量的图片、视频、文档等。由于采用Golang实现,服务端可以工作在Windows、Linux、 OS X和FreeBSD上。配置简单,基本是复制可执行程序,单行命令就可以运行起来。
MinIO兼容亚马逊S3(Simple Storage Service,简单存储服务)云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而且每个对象文件可以是任意大小,从几kb到最大5T不等。
MinIO特点:
1. 高性能:作为高性能对象存储,在标准硬件条件下它能达到55GB/s的读、35GB/s的写速率;
2. 可扩容:不同MinIO集群可以组成联邦,并形成一个全局的命名空间,并跨越多个数据中心;
3. SDK支持: 基于Minio轻量的特点,它得到类似Java、Python或Go等语言的sdk支持;
4. 支持纠删码:MinIO使用纠删码、Checksum来防止硬件错误和静默数据污染。在最高冗余度配 置下,即使丢失1/2的磁盘也能恢复数据;
MinIO基本概念:
在home/docker/minio文件夹下创建两个文件夹,分别是data、config,用于挂载容器中的数据卷。
- mkdir home/docker/minio/data
- mkdir home/docker/minio/config
docker pull minio/minio
- docker run -p 9000:9000 -p 9001:9001\
- --name minio \
- -d --restart=always \
- -e "MINIO_ROOT_USER=minio" \
- -e "MINIO_ROOT_PASSWORD=minio123" \
- -v /home/docker/minio/data:/data \
- -v /home/docker/minio/config \
- minio/minio server \
- /data --console-address ":9001" -address ":9000"
参数说明
记得开放安全组!
docker logs minio容器id
通过以上命令查看 minio 日志,会输出以下内容:
我们可以通过日志中的Console地址来访问可视化界面。
登录成功后,可以创建桶
此时在桶列表会会出现刚刚创建的桶,点击Manage,设置桶的访问策略,修改为 Public 公共策略,这样 minio 中的文件才能被外界访问
并可以直接在桶中上传文件。
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- </dependency>
-
- <!-- 必须要导入OKhttp的依赖 -->
- <dependency>
- <groupId>com.squareup.okhttp3</groupId>
- <artifactId>okhttp</artifactId>
- <version>4.8.1</version>
- </dependency>
-
- <!-- https://mvnrepository.com/artifact/io.minio/minio -->
- <dependency>
- <groupId>io.minio</groupId>
- <artifactId>minio</artifactId>
- <version>8.5.7</version>
- </dependency>
-
- <!--web-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <!--lombok-->
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- </dependencies>

在 yaml 中新增以下配置:
- minio:
- accessKey: minio # 访问Key
- secretKey: minio123 # 密钥
- bucket: test
- endpoint: http://xxx.x.x.x:9000 # ip:api端口
- readPath: http://xxx.x.x.x:9000 # ip:api端口
- servlet:
- multipart:
- # 单个上传文件的最大值是200mb
- max-file-size: 200MB
- # 单次请求的最大值
- max-request-size: 200MB
- @Data
- @Component
- @ConfigurationProperties(prefix = "minio") //自动注入属性前缀为minio的配置
- public class MinIOConfigProperties implements Serializable {
-
- private String accessKey; // 访问key
- private String secretKey; // 秘钥
- private String bucket; // 桶
- private String endpoint; // 地域节点
- private String readPath; // 读取路径
- }
- @Configuration
- public class MinIOConfig {
-
- @Autowired
- private MinIOConfigProperties minIOConfigProperties;
-
- // 注册MinIO实例
- @Bean
- public MinioClient buildMinioClient(){
- return MinioClient
- .builder()
- .credentials(minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey())
- .endpoint(minIOConfigProperties.getEndpoint())
- .build();
- }
- }

- public interface FileStorageService {
-
- /**
- * 上传图片文件
- *
- * @param prefix 文件前缀
- * @param filename 文件名
- * @param inputStream 文件流
- * @return 文件全路径
- */
- public String uploadImgFile(String prefix, String filename, InputStream inputStream);
-
- /**
- * 上传html文件
- *
- * @param prefix 文件前缀
- * @param filename 文件名
- * @param inputStream 文件流
- * @return 文件全路径
- */
- public String uploadHtmlFile(String prefix, String filename, InputStream inputStream);
-
- /**
- * 删除文件
- *
- * @param pathUrl 文件全路径
- */
- public void delete(String pathUrl);
-
- /**
- * 下载文件
- *
- * @param pathUrl 文件全路径
- * @return
- */
- public byte[] downLoadFile(String pathUrl);
-
- }

业务接口实现类:
- @Service
- public class MinIOFileStorageService implements FileStorageService {
- @Autowired
- MinioClient minioClient;
-
- @Autowired
- MinIOConfigProperties minIOConfigProperties;
-
- final static String separator = "/"; //文件夹分隔符
-
- /**
- * 构建文件的绝对路径
- *
- * @param dirPath 文件路径
- * @param filename 文件名 yyyy/mm/dd/file.jpg
- * @return /test
- */
- 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();
- }
-
- /**
- * 上传图片文件
- *
- * @param prefix 文件前缀
- * @param filename 文件名
- * @param inputStream 文件流
- * @return 文件全路径
- */
- @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) {
- throw new RuntimeException("上传文件失败");
- }
- }
-
- /**
- * 上传html文件
- *
- * @param prefix 文件前缀
- * @param filename 文件名
- * @param inputStream 文件流
- * @return 文件全路径
- */
- @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())//桶名称与minio创建的桶一致
- .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) {
- ex.printStackTrace();
- throw new RuntimeException("上传文件失败");
- }
- }
-
- /**
- * 删除文件
- *
- * @param pathUrl 文件全路径
- */
- @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);
- // 删除Objects
- RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();
- try {
- minioClient.removeObject(removeObjectArgs);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
-
- /**
- * 下载文件
- *
- * @param pathUrl 文件全路径
- * @return 文件流
- */
- @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) {
- 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();
- }
-
- }

- @RestController
- @RequestMapping("/minio")
- public class MinioController {
-
- @Autowired
- private FileStorageService fileStorageService;
-
- /**
- * 上传图片到minio
- *
- * @param file
- * @return
- */
- @PostMapping("/upload")
- public void uploadFile(MultipartFile file) throws IOException {
- try {
- // 获取文件名称
- String fileName = file.getOriginalFilename();
- /*解决多次上传同名文件覆盖问题*/
- // 在文件名称里面添加随机唯一的值
- String uuid = UUID.randomUUID().toString().replaceAll("-", "");
- fileName = uuid + fileName;
- // 获取文件输入流
- InputStream is = file.getInputStream();
- String imgUrl = fileStorageService.uploadImgFile("img", fileName, is);
- return "上传成功!imgUrl:"+imgUrl;
- } catch (IOException e) {
- e.printStackTrace();
- return "上传失败";
- }
- }
-
- }

查看 Minio 可视化界面图片是否上传成功
可通过ip+图片路径直接访问。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。