Spring Boot + minio 实现高性能存储服务,So Easy~!

打印 上一主题 下一主题

主题 938|帖子 938|积分 2814

什么是minio

引用官网:
MinIO是根据GNU Affero通用公共许可证v3.0发布的高性能对象存储。它与Amazon S3云存储服务兼容。使用MinIO构建用于机器学习,分析和应用程序数据工作负载的高性能基础架构。
官网地址:
https://min.io/
文档地址:
https://docs.min.io/
一. 使用docker 搭建minio 服务。

GNU / Linux和macOS
  1. docker run -p 9000:9000 \
  2.   --name minio1 \
  3.   -v /mnt/data:/data \
  4.   -e "MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE" \
  5.   -e "MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
  6.   minio/minio server /data
复制代码
windows
  1. docker run -p 9000:9000 \
  2.   --name minio1 \
  3.   -v D:\data:/data \
  4.   -e "MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE" \
  5.   -e "MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
  6.   minio/minio server /data
复制代码

  • MINIO_ROOT_USER:为用户key
  • MINIO_ROOT_PASSWORD:为用户密钥
以上搭建的都是单机版的。想要了解分布式 的方式请查看官网文档。

这就是在win的docker上运行的。
当启动后在浏览器访问http://localhost:9000就可以访问minio的图形化界面了,如图所示:


二. 下面开始搭建springboot 环境

初始化一个springboot项目大家都会,这里不多做介绍。
推荐一个 Spring Boot 基础教程及实战示例:https://github.com/javastacks/spring-boot-best-practice
主要是介绍需要引入的依赖:
  1.   <dependency>
  2.             <groupId>org.springframework.boot</groupId>
  3.             <artifactId>spring-boot-starter-thymeleaf</artifactId>
  4.         </dependency>
  5.          <dependency>
  6.             <groupId>io.minio</groupId>
  7.             <artifactId>minio</artifactId>
  8.             <version>8.2.1</version>
  9.         </dependency>
  10.          <dependency>
  11.             <groupId>org.projectlombok</groupId>
  12.             <artifactId>lombok</artifactId>
  13.             <optional>true</optional>
  14.         </dependency>
复制代码
依赖可以官方文档里找:https://docs.min.io/docs/java-client-quickstart-guide.html
下面介绍配置文件:
  1. spring:
  2.   servlet:
  3.     multipart:
  4.       max-file-size: 10MB
  5.       max-request-size: 10MB
  6. #minio配置
  7.   minio:
  8.     access-key: AKIAIOSFODNN7EXAMPLE      #key就是docker初始化是设置的,密钥相同
  9.     secret-key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  10.     url: http://localhost:9000
  11.     bucket-name: wdhcr
  12.   thymeleaf:
  13.     cache: false
复制代码
创建minio的配置类:
  1. @Configuration
  2. @ConfigurationProperties(prefix = "spring.minio")
  3. @Data
  4. public class MinioConfiguration {
  5.     private String accessKey;
  6.     private String secretKey;
  7.     private String url;
  8.     private String bucketName;
  9.     @Bean
  10.     public MinioClient minioClient() {
  11.         return MinioClient.builder()
  12.                 .endpoint(url)
  13.                 .credentials(accessKey, secretKey)
  14.                 .build();
  15.     }
  16. }
复制代码
使用配置属性绑定进行参数绑定,并初始化一个minio client对象放入容器中。
下面就是我封装的minio client 操作minio的简单方法的组件。
  1. @Component
  2. public class MinioComp {
  3.     @Autowired
  4.     private MinioClient minioClient;
  5.     @Autowired
  6.     private MinioConfiguration configuration;
  7.     /**
  8.      * @description: 获取上传临时签名
  9.      * @dateTime: 2021/5/13 14:12
  10.      */
  11.     public Map getPolicy(String fileName, ZonedDateTime time) {
  12.         PostPolicy postPolicy = new PostPolicy(configuration.getBucketName(), time);
  13.         postPolicy.addEqualsCondition("key", fileName);
  14.         try {
  15.             Map<String, String> map = minioClient.getPresignedPostFormData(postPolicy);
  16.             HashMap<String, String> map1 = new HashMap<>();
  17.             map.forEach((k,v)->{
  18.                map1.put(k.replaceAll("-",""),v);
  19.            });
  20.             map1.put("host",configuration.getUrl()+"/"+configuration.getBucketName());
  21.             return map1;
  22.         } catch (ErrorResponseException e) {
  23.             e.printStackTrace();
  24.         } catch (InsufficientDataException e) {
  25.             e.printStackTrace();
  26.         } catch (InternalException e) {
  27.             e.printStackTrace();
  28.         } catch (InvalidKeyException e) {
  29.             e.printStackTrace();
  30.         } catch (InvalidResponseException e) {
  31.             e.printStackTrace();
  32.         } catch (IOException e) {
  33.             e.printStackTrace();
  34.         } catch (NoSuchAlgorithmException e) {
  35.             e.printStackTrace();
  36.         } catch (ServerException e) {
  37.             e.printStackTrace();
  38.         } catch (XmlParserException e) {
  39.             e.printStackTrace();
  40.         }
  41.         return null;
  42.     }
  43.     /**
  44.      * @description: 获取上传文件的url
  45.      * @dateTime: 2021/5/13 14:15
  46.      */
  47.     public String getPolicyUrl(String objectName, Method method, int time, TimeUnit timeUnit) {
  48.         try {
  49.             return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
  50.                     .method(method)
  51.                     .bucket(configuration.getBucketName())
  52.                     .object(objectName)
  53.                     .expiry(time, timeUnit).build());
  54.         } catch (ErrorResponseException e) {
  55.             e.printStackTrace();
  56.         } catch (InsufficientDataException e) {
  57.             e.printStackTrace();
  58.         } catch (InternalException e) {
  59.             e.printStackTrace();
  60.         } catch (InvalidKeyException e) {
  61.             e.printStackTrace();
  62.         } catch (InvalidResponseException e) {
  63.             e.printStackTrace();
  64.         } catch (IOException e) {
  65.             e.printStackTrace();
  66.         } catch (NoSuchAlgorithmException e) {
  67.             e.printStackTrace();
  68.         } catch (XmlParserException e) {
  69.             e.printStackTrace();
  70.         } catch (ServerException e) {
  71.             e.printStackTrace();
  72.         }
  73.         return null;
  74.     }
  75.     /**
  76.      * @description: 上传文件
  77.      * @dateTime: 2021/5/13 14:17
  78.      */
  79.     public void upload(MultipartFile file, String fileName) {
  80.         // 使用putObject上传一个文件到存储桶中。
  81.         try {
  82.             InputStream inputStream = file.getInputStream();
  83.             minioClient.putObject(PutObjectArgs.builder()
  84.                     .bucket(configuration.getBucketName())
  85.                     .object(fileName)
  86.                     .stream(inputStream, file.getSize(), -1)
  87.                     .contentType(file.getContentType())
  88.                     .build());
  89.         } catch (ErrorResponseException e) {
  90.             e.printStackTrace();
  91.         } catch (InsufficientDataException e) {
  92.             e.printStackTrace();
  93.         } catch (InternalException e) {
  94.             e.printStackTrace();
  95.         } catch (InvalidKeyException e) {
  96.             e.printStackTrace();
  97.         } catch (InvalidResponseException e) {
  98.             e.printStackTrace();
  99.         } catch (IOException e) {
  100.             e.printStackTrace();
  101.         } catch (NoSuchAlgorithmException e) {
  102.             e.printStackTrace();
  103.         } catch (ServerException e) {
  104.             e.printStackTrace();
  105.         } catch (XmlParserException e) {
  106.             e.printStackTrace();
  107.         }
  108.     }
  109.   /**
  110.      * @description: 根据filename获取文件访问地址
  111.      * @dateTime: 2021/5/17 11:28
  112.      */
  113.     public String getUrl(String objectName, int time, TimeUnit timeUnit) {
  114.         String url = null;
  115.         try {
  116.             url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
  117.                     .method(Method.GET)
  118.                     .bucket(configuration.getBucketName())
  119.                     .object(objectName)
  120.                     .expiry(time, timeUnit).build());
  121.         } catch (ErrorResponseException e) {
  122.             e.printStackTrace();
  123.         } catch (InsufficientDataException e) {
  124.             e.printStackTrace();
  125.         } catch (InternalException e) {
  126.             e.printStackTrace();
  127.         } catch (InvalidKeyException e) {
  128.             e.printStackTrace();
  129.         } catch (InvalidResponseException e) {
  130.             e.printStackTrace();
  131.         } catch (IOException e) {
  132.             e.printStackTrace();
  133.         } catch (NoSuchAlgorithmException e) {
  134.             e.printStackTrace();
  135.         } catch (XmlParserException e) {
  136.             e.printStackTrace();
  137.         } catch (ServerException e) {
  138.             e.printStackTrace();
  139.         }
  140.         return url;
  141.     }
  142. }
复制代码
简单说明:

  • 使用MultipartFile接收前端文件流,再上传到minio。
  • 构建一个formData的签名数据,给前端,让前端之前上传到minio。
  • 构建一个可以上传的临时URL给前端,前端通过携带文件请求该URL进行上传。
  • 使用filename请求服务端获取临时访问文件的URL。(最长时间为7 天,想要永久性访问,需要其他设置,这里不做说明。)
下面展示页面html,使用的是VUE+element-ui进行渲染。
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="UTF-8">
  5.    
  6.     <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
  7.     <title>上传图片</title>
  8. </head>
  9. <body>
  10.     <el-row :gutter="2">
  11.         <el-col :span="8">
  12.             
  13.                
  14.                     <center><h3>传统上传</h3></center>
  15.                     <el-upload
  16.                            
  17.                             action="#"
  18.                             drag
  19.                             :http-request="uploadHandle">
  20.                         <i ></i>
  21.                         将文件拖到此处,或<em>点击上传</em>
  22.                         只能上传jpg/png文件,且不超过500kb
  23.                     </el-upload>
  24.                     
  25.                         <img :src="imgUrl" ></img>
  26.                     
  27.                
  28.             
  29.         </el-col>
  30.         <el-col :span="8">
  31.             
  32.                
  33.                     <center><h3>前端formData直传</h3></center>
  34.                     <el-upload
  35.                            
  36.                             action="#"
  37.                             drag
  38.                             :http-request="httpRequestHandle">
  39.                         <i ></i>
  40.                         将文件拖到此处,或<em>点击上传</em>
  41.                         只能上传jpg/png文件,且不超过500kb
  42.                     </el-upload>
  43.                     
  44.                         <img :src="directUrl" ></img>
  45.                     
  46.                
  47.             
  48.         </el-col>
  49.         <el-col :span="8">
  50.             
  51.                
  52.                     <center><h3>前端Url直传</h3></center>
  53.                     <el-upload
  54.                            
  55.                             action="#"
  56.                             drag
  57.                             :http-request="UrlUploadHandle">
  58.                         <i ></i>
  59.                         将文件拖到此处,或<em>点击上传</em>
  60.                         只能上传jpg/png文件,且不超过500kb
  61.                     </el-upload>
  62.                     
  63.                         <img :src="uploadUrl" ></img>
  64.                     
  65.                
  66.             
  67.         </el-col>
  68.     </el-row>
  69. </body>
  70. </html>
复制代码
页面效果


可以分别体验不同的实现效果。
以上就是使用springboot搭建基于minio的高性能存储服务的全部步骤了。
项目地址:https://gitee.com/jack_whh/minio-upload
原文链接:https://blog.csdn.net/weixin_45089791/article/details/116921075
版权声明:本文为CSDN博主「HUWD」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
近期热文推荐:
1.1,000+ 道 Java面试题及答案整理(2022最新版)
2.劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!
5.《Java开发手册(嵩山版)》最新发布,速速下载!
觉得不错,别忘了随手点赞+转发哦!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

西河刘卡车医

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表