MinIO基于Apache License 2.0开源协议的对象存储服务。它兼容Amazon S3云存储接口。适合存储非结构化数据,如图片,音频,视频,日志等。
MinIo
基础概念
Object
:存储到Minio
的基本对象,如文件字节流,AnythingBucket
:用来存储Object
的逻辑空间。每个Bucket
之间的数据是相互隔离的。对于客户端而言,就相当于一个存放文件的顶层文件夹。Drive
:即存储数据的磁盘,在MiniO
启动时,以参数的方式传入。Minio
中所有的对象数据都会存储在Drive里Set
:即-组Drive
的集合,分布式部署根据集群规模自动划分一个或多个Set
,每个Set
中的Drive
分布在不同位置。一个对象存
储在一个Set
上。一个对象存储在一个Set
上,一个集群划分为多个Set
,一个Set
包含的Drive
数量是固定的,默认由系统根据集群规模自动计算得出
一个Set
中的Drive
尽可能分布在不同的节点上。
docker
运行
本次直接基于Docker
来运行MinIo
拉取镜像
docker pull minio/minio
运行镜像
docker run --privileged -d -it -p 9000:9000 -p 9111:9111--name minio -e "MINIO_ROOT_USER=minioadmin" --privileged=true-e "MINIO_ROOT_PASSWORD=minio@123456"-v /Users/wangyupeng/data/minio/data:/data-v /Users/wangyupeng/data/minio/config:/root/.minio minio/minio server /data--console-address ":9111" -address ":9000"
- 运行命令,重要参数说明
--privileged
container
内的root
拥有真正的root
权限。否则,container
内的root
只是外部的一个普通用户权限。
privileged
启动的容器,可以看到很多host
上的设备,并且可以执行mount
。甚至允许你在docker
容器中启动docker
容器。
MINIO_ROOT_USER
登陆管理界面的用户名
MINIO_ROOT_PASSWORD
登陆管理页面密码
-V
第一个
-v
是设置数据存放目录,第二个-v
是配置目录
--console-address
管理界面 端口设置,一定要和其中一个
-p
参数的端口对上,不指定的话会随机分配端口
-address
api
访问端口
--name
容器运行的名字
查看运行日志
docker logs minio
- 出现下面的日志,表示容器运行成功
访问minio
浏览器输入http://127.0.0.1:9111
,输入设置的MINIO_ROOT_USER
和MINIO_ROOT_PASSWORD
就能登录了,到此我们已经将minio
运行起来了。
SpringBoot
整合MinIO
引入依赖
io.minio minio 8.5.2
配置
server: port: 9999spring: servlet: multipart: max-file-size: 10MB max-request-size: 10MB minio: access-key: minioadmin #key就是docker初始化是设置的,密钥相同 secret-key: minio@123456 url: http://localhost:9000 bucket-name: admin # 登陆minio创建的文件桶
构建配置类
package org.triumphxx.minio.config;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;@Configuration@ConfigurationProperties(prefix = "spring.minio")@Datapublic class MinioConfiguration { private String accessKey; private String secretKey; private String url; private String bucketName; @Bean public MinioClient minioClient() { return MinioClient.builder() .endpoint(url) .credentials(accessKey, secretKey) .build(); }}
构建操作minio的服务类
package org.triumphxx.minio.service;import io.minio.GetPresignedObjectUrlArgs;import io.minio.MinioClient;import io.minio.PostPolicy;import io.minio.PutObjectArgs;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.web.multipart.MultipartFile;import org.triumphxx.minio.config.MinioConfiguration;import io.minio.http.Method;import java.io.InputStream;import java.time.ZonedDateTime;import java.util.HashMap;import java.util.Map;import java.util.concurrent.TimeUnit;@Service@Slf4jpublic class MinIoService { @Autowired private MinioClient minioClient; @Autowired private MinioConfiguration configuration; public Map getPolicyUrl(String fileName, ZonedDateTime time) { PostPolicy postPolicy = new PostPolicy(configuration.getBucketName(), time); postPolicy.addEqualsCondition("key", fileName); try { Map<String, String> map = minioClient.getPresignedPostFormData(postPolicy); HashMap<String, String> policyMap = new HashMap<>(); map.forEach((k,v)->{ policyMap.put(k.replaceAll("-",""),v); }); policyMap.put("host",configuration.getUrl()+"/"+configuration.getBucketName()); return policyMap; } catch (Exception e) { e.printStackTrace(); } return null; } public String getFileUrl(String objectName,int time, TimeUnit timeUnit) { try { return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder() .method(Method.GET) .bucket(configuration.getBucketName()) .object(objectName) .expiry(time, timeUnit).build()); } catch (Exception e) { e.printStackTrace(); } return null; } public void uploadToFile(MultipartFile file) { // 使用putObject上传一个文件到存储桶中。 try { InputStream inputStream = file.getInputStream(); String fileName = file.getOriginalFilename(); log.info("上传的文件名为:{}",fileName); minioClient.putObject(PutObjectArgs.builder() .bucket(configuration.getBucketName()) .object(fileName.substring(0,fileName.indexOf("."))) .stream(inputStream, file.getSize(), -1) .contentType(file.getContentType()) .build()); } catch (Exception e){ e.printStackTrace(); } } public String getUrl(String objectName, int time, TimeUnit timeUnit) { String url = null; try { url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder() .method(Method.GET) .bucket(configuration.getBucketName()) .object(objectName) .expiry(time, timeUnit).build()); }catch (Exception e){ e.printStackTrace(); } return url; }}
创建测试类
package org.triumphxx.minio.controller;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import org.triumphxx.minio.service.MinIoService;import javax.annotation.Resource;import java.time.ZonedDateTime;import java.util.Map;import java.util.concurrent.TimeUnit;@RestControllerpublic class MinIoController { @Resource MinIoService minIoService; @PostMapping("/upload") public void uploadToFile(@RequestParam("file") MultipartFile file){ minIoService.uploadToFile(file); } @PostMapping("/uploadToFileInputStream") public void uploadToFileInputStream(@RequestParam("file") MultipartFile file){ minIoService.uploadToFile(file); } @GetMapping("/getFileUrl") public String getFileUrl(@RequestParam("name") String name , @RequestParam("time") int time){ return minIoService.getUrl(name,time, TimeUnit.DAYS); } @PostMapping("/getPolicyUrl") public Map getPolicyUrl(@RequestParam("name") String name){ return minIoService.getPolicyUrl(name, ZonedDateTime.now()); } @PostMapping("/getTempFileUrl") public String getTempFileUrl(@RequestParam("name") String name, @RequestParam("time") int time){ return minIoService.getFileUrl(name, time,TimeUnit.DAYS); }}
使用postman测试
查看上传的图片
看到如下图片表示上传成功!
小结
本篇文章,一起探讨了使用docker
运行minio
,并且使用springboot
整合,实现文件的上传。 源码地址源码传送门
来源地址:https://blog.csdn.net/weixin_45077847/article/details/131265360