使用springboot搭建基于minio的高性能存储服务

什么是minio

引用官网:

MinIO是根据GNU Affero通用公共许可证v3.0发布的高性能对象存储。它与Amazon S3云存储服务兼容。使用MinIO构建用于机器学习,分析和应用程序数据工作负载的高性能基础架构。

官网地址
文档地址

一. 使用docker 搭建minio 服务。

  • GNU / Linux和macOS
docker run -p 9000:9000 \
  --name minio1 \
  -v /mnt/data:/data \
  -e "MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE" \
  -e "MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
  minio/minio server /data
  • windows
docker run -p 9000:9000 \
  --name minio1 \
  -v D:\data:/data \
  -e "MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE" \
  -e "MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
  minio/minio server /data

MINIO_ROOT_USER: 为用户key
MINIO_ROOT_PASSWORD: 为用户密钥

  • 以上搭建的都是单机版的。想要了解分布式 的方式请查看官网文档。

在这里插入图片描述
这就是在win的docker上运行的。

当启动后在浏览器访问http://localhost:9000就可以访问minio的图形化界面了,如图所示:
使用springboot搭建基于minio的高性能存储服务_第1张图片
使用springboot搭建基于minio的高性能存储服务_第2张图片

docker如何在windows 上运行,请参考这篇文章

二. 下面开始搭建springboot 环境

  • 初始化一个springboot项目大家都会,这里不多做介绍。
  • 主要是介绍需要引入的依赖:

		
            org.springframework.boot
            spring-boot-starter-thymeleaf
        

         
            io.minio
            minio
            8.2.1
        

         
            org.projectlombok
            lombok
            true
        

依赖可以官方文档里找:https://docs.min.io/docs/java-client-quickstart-guide.html

  • 下面介绍配置文件:
spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB
#minio配置
  minio:
    access-key: AKIAIOSFODNN7EXAMPLE      #key就是docker初始化是设置的,密钥相同
    secret-key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
    url: http://localhost:9000
    bucket-name: wdhcr
  thymeleaf:
    cache: false

创建minio的配置类:

@Configuration
@ConfigurationProperties(prefix = "spring.minio")
@Data
public 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 client对象放入容器中。

  • 下面就是我封装的minio client 操作minio的简单方法的组件。
@Component
public class MinioComp {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfiguration configuration;

    /**
     * @description: 获取上传临时签名
     * @dateTime: 2021/5/13 14:12
     */
    public Map getPolicy(String fileName, ZonedDateTime time) {
        PostPolicy postPolicy = new PostPolicy(configuration.getBucketName(), time);
        postPolicy.addEqualsCondition("key", fileName);
        try {
            Map map = minioClient.getPresignedPostFormData(postPolicy);
            HashMap map1 = new HashMap<>();
            map.forEach((k,v)->{
               map1.put(k.replaceAll("-",""),v);
           });
            map1.put("host",configuration.getUrl()+"/"+configuration.getBucketName());
            return map1;
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @description: 获取上传文件的url
     * @dateTime: 2021/5/13 14:15
     */
    public String getPolicyUrl(String objectName, Method method, int time, TimeUnit timeUnit) {
        try {
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(method)
                    .bucket(configuration.getBucketName())
                    .object(objectName)
                    .expiry(time, timeUnit).build());
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * @description: 上传文件
     * @dateTime: 2021/5/13 14:17
     */
    public void upload(MultipartFile file, String fileName) {
        // 使用putObject上传一个文件到存储桶中。
        try {
            InputStream inputStream = file.getInputStream();
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(configuration.getBucketName())
                    .object(fileName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        }
    }
 	/**
     * @description: 根据filename获取文件访问地址
     * @dateTime: 2021/5/17 11:28
     */
    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 (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        }
        return url;
    }
}

简单说明:

  1. 使用MultipartFile接收前端文件流,再上传到minio。
  2. 构建一个formData的签名数据,给前端,让前端之前上传到minio。
  3. 构建一个可以上传的临时URL给前端,前端通过携带文件请求该URL进行上传。
  4. 使用filename请求服务端获取临时访问文件的URL。(最长时间为7 天,想要永久性访问,需要其他设置,这里不做说明。)
  • 下面展示页面html,使用的是VUE+element-ui进行渲染。



    
    
    
    上传图片


传统上传

将文件拖到此处,或点击上传
只能上传jpg/png文件,且不超过500kb

前端formData直传

将文件拖到此处,或点击上传
只能上传jpg/png文件,且不超过500kb

前端Url直传

将文件拖到此处,或点击上传
只能上传jpg/png文件,且不超过500kb

使用springboot搭建基于minio的高性能存储服务_第3张图片
页面的效果就如上图所示。
可以分别体验不同的实现效果。

以上就是使用springboot搭建基于minio的高性能存储服务的全部步骤了。

项目地址是:https://gitee.com/jack_whh/minio-upload 项目地址

你可能感兴趣的:(文件存储服务,minio,高性能文件存储服务)