MinIO(对象存储服务)

简介

MinIO基于Apache License v2.0开源协议的对象存储服务,可以做为云存储的解决方案用来保存海量的图片,视频,文档。由于采用Golang实现,服务端可以工作在Windows,Linux, OS X和FreeBSD上。配置简单,基本是复制可执行程序,单行命令可以运行起来。

MinIO兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。

入门

1.导入pom依赖

    <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>

2.配置类

  1. MinIOConfigProperties

     @Data
     @ConfigurationProperties(prefix = "minio")  // 文件上传 配置前缀file.oss
     public class MinIOConfigProperties implements Serializable {
     
       private String accessKey;
       private String secretKey;
       private String bucket;
       private String endpoint;
       private String readPath;
     }
    
  2. MinIOConfigProperties

     @Data
     @Configuration
     @EnableConfigurationProperties({MinIOConfigProperties.class})
     //当引入FileStorageService接口时
     @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.封装操作minIO类

  1. FileStorageService

    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);
    
    }
    
  2. MinIOFileStorageService

    @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 = "/";
    
        /**
         * @param dirPath
         * @param filename  yyyy/mm/dd/file.jpg
         * @return
         */
        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){
                log.error("minio put file error.",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()).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("上传文件失败");
            }
        }
    
        /**
         * 删除文件
         * @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) {
                log.error("minio remove file error.  pathUrl:{}",pathUrl);
                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) {
                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();
        }
    }
    

4.对外加入自动配置

在resources中新建META-INF/spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  MinIOFileStorageService路径

使用方法

1.添加minio所需要的配置

spring:
  # 配置文件上传大小限制(minio文件上传)
  servlet:
    multipart:
      max-file-size: 200MB
      max-request-size: 200MB

minio:
  accessKey: minio
  secretKey: minio123
  bucket: 文件在minio中的主目录命名
  endpoint: http://主机IP:9000
  readPath: http://主机IP:9000

2.在对应使用的业务类中注入FileStorageService

例:

@SpringBootTest(classes = MinioApplication.class)
@RunWith(SpringRunner.class)
public class MinioTest {

    @Autowired
    private FileStorageService fileStorageService;

    @Test
    public void testUpdateImgFile() {
        try {
            FileInputStream fileInputStream = new FileInputStream("E:\\tmp\\ak47.jpg");
            String filePath = fileStorageService.uploadImgFile("", "ak47.jpg", fileInputStream);
            System.out.println(filePath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

#安装(使用DOCKER)

  1. 拉取镜像

    docker pull minio/minio
    
  2. 部署容器

    docker run -p 9000:9000 --name minio -d --restart=always -e "MINIO_ACCESS_KEY=minio" -e "MINIO_SECRET_KEY=minio123" -v /home/data:/data -v /home/config:/root/.minio minio/minio server /data
    
posted @ 2023-02-05 20:33  xuruiRyan  阅读(416)  评论(0编辑  收藏  举报