likes
comments
collection
share

Minio基于docker的基本使用

作者站长头像
站长
· 阅读数 18

一、Minio的基本介绍

MinIO 是一种对象存储解决方案,提供与亚马逊云科技 S3 兼容的 API,并支持所有核心 S3 功能。MinIO 专为部署在任何地方而构建 - 公共云或私有云、裸机基础架构、编排环境和边缘基础架构。

二、Minio的基本概念

  1. Object:存储到MinIO的基本对象,即对文件的抽象。如文件,字节流等
  2. Bucket:存储Object的逻辑空间,每个Bucket之间的数据时相互隔离的。对于用户而言,相当于存放文件的顶层文件夹。
  3. Drive:存储Object的磁盘。在MinIO启动时,以参数的方式传入。
  4. Set:一组Drive的集合。根据集群规模自动划分Set,每个Set中的Drive分布在不同位置。
  5. EC:纠删码(Erasure Code),用来把丢失的数据进行恢复。

Minio存储文件时,会在对应的数据存储磁盘中,以Bucket名称为目录,文件名称为下一级目录,文件名下是xl.meta,通过奇偶的形式存储 编码数据块及检验块和元数据文件。

三、Docker安装Minio

1、拉去minio镜像

docker search minio
docker push 镜像名称

2、执行minio镜像具体可参考官网

docker run \
   -p 9000:9000 \ #服务端端口
   -p 9090:9090 \ #客户端端口
   --name minio1 \ #容器名称
   -v D:\ProjectSpace\data:/data \ #文件存放路径
   -e "MINIO_ACCESS_KEY=admin" \ #管理平台账号
   -e "MINIO_SECRET_KEY=admin123" \ #密码
   quay.io/minio/minio server /data --console-address ":9090" #指定客户端端口

Minio基于docker的基本使用

三、Spring Boot 整合 Minio

1、导入Minio依赖

<!--minio-->  
<dependency>  
    <groupId>io.minio</groupId>  
    <artifactId>minio</artifactId>  
    <version>8.0.3</version>  
</dependency>

2、编写application.yml

spring:  
    servlet:  
        multipart:  
            max-file-size: 200MB  
            max-request-size: 200MB  
  
server:  
    port: 8090  
  
minio:  
    endpoint: http://127.0.0.1:9000  
    accessKey: admin  
    secretKey: admin123  
    bucketName: picture

3、编写配置类

@Component  
public class MinioClientConfig {  
    @Value("${minio.endpoint}")  
    private String endpoint;  
    @Value("${minio.accessKey}")  
    private String accessKey;  
    @Value("${minio.secretKey}")  
    private String secretKey;  
  
    @Bean  
    public MinioClient minioClient() {  
        return MinioClient.builder()  
            .endpoint(endpoint)  
            .credentials(accessKey, secretKey)  
            .build();  
    }  
}

4、编写工具类

@Setter  
@Getter  
@AllArgsConstructor  
public class CommonResult {  
  
    /**  
    * 状态码  
    */  
    private int code;  

    /**  
    * 响应信息  
    */  
    private String message;  

    /**  
    * 响应数据  
    */  
    private Object data;  

    public static CommonResult success() {  
        return new CommonResult(200, "success", null);  
    }  

    public static CommonResult success(Object data) {  
        return new CommonResult(200, "success", data);  
    }  

    public static CommonResult fail(String message) {  
        return new CommonResult(400, message, null);  
    }  
}
  • 判断Bucket是否存在
    @Autowired  
    private MinioClient minioClient;
    
    /**  
    * Bucket是否存在  
    *  
    * @param bucketName  
    * @return  
    */  
    public boolean bucketExisted(String bucketName) {  
        boolean isExist = false;  
        try {  
            isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());  
        } catch (Exception ex) {  
            log.info("bucketExisted error: {}", ex.getMessage());  
            return false;  
        }  
        return isExist;  
    }
  • 创建Bucket
    @Autowired  
    private MinioClient minioClient;
    
    /**  
    * 创建Bucket  
    *  
    * @param bucketName  
    * @return  
    */  
    public boolean createBucket(String bucketName) {  
        try {  
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());  
        } catch (Exception ex) {  
            log.info("createBucket error: {}", ex.getMessage());  
            return false;  
        }  
        return true;  
    }
  • 删除Bucket
    @Autowired  
    private MinioClient minioClient;
    
    /**  
    * 删除Bucket  
    *  
    * @param bucketName  
    * @return  
    */  
    public boolean deleteBucket(String bucketName) {  
        try {  
            minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());  
        } catch (Exception ex) {  
            log.info("deleteBucket error: {}", ex.getMessage());  
            return false;  
        }  
        return true;  
    }
  • 获取所有Bucket
    @Autowired  
    private MinioClient minioClient;
    
    /**  
    * 获取所有Bucket  
    *  
    * @return  
    */  
    public List<Bucket> getAllBuckets() {  
        List<Bucket> buckets = null;  
        try {  
            minioClient.listBuckets();  
        } catch (Exception ex) {  
            log.info("getAllBuckets error: {}", ex.getMessage());  
        }  
        return (buckets == null) ? new ArrayList<>() : buckets;  
    }
  • 文件上传
    @Autowired  
    private MinioClient minioClient;
    
    /**  
    * 上传文件  
    *  
    * @param file  
    * @param bucketName  
    * @return 文件名  
    */  
    public String uploadFile(MultipartFile file, String bucketName) {  
        String originalFilename = file.getOriginalFilename();  
        String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));  
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");  
        String objectName = simpleDateFormat.format(new Date()) + "_" + fileName;  
        try {  
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()  
                .bucket(bucketName)  
                .object(objectName)  
                .stream(file.getInputStream(), file.getSize(), -1)  
                .contentType(file.getContentType()).build();  
            minioClient.putObject(putObjectArgs);  
        } catch (Exception ex) {  
            log.info("uploadFile error: {}", ex.getMessage());  
            return null;  
        }  
        return objectName;  
    }
  • 文件下载
    @Autowired  
    private MinioClient minioClient;
    
    /**  
    * 根据文件名下载文件  
    *  
    * @param fileName  
    * @param bucketName  
    * @param res  
    */  
    public void download(String fileName, String bucketName, HttpServletResponse res) {  
        GetObjectArgs getObjectArgs = GetObjectArgs.builder().bucket(bucketName).object(fileName).build();  
        FastByteArrayOutputStream os = null;  
        try (GetObjectResponse response = minioClient.getObject(getObjectArgs)) {  
            byte[] buf = new byte[1024];  
            int len;  
            os = new FastByteArrayOutputStream();  
            while ((len = response.read(buf)) != -1) {  
                os.write(buf, 0, len);  
            }  
            os.flush();  
            res.setCharacterEncoding("utf-8");  
            res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);  
            try (ServletOutputStream outputStream = res.getOutputStream()) {  
                outputStream.write(os.toByteArray());  
                outputStream.flush();  
            }  
        } catch (Exception ex) {  
            log.info("download error: {}", ex.getMessage());  
        } finally {  
            os.close();  
        }  
    }
  • 获取文件地址
    @Autowired  
    private MinioClient minioClient;
    
    /**  
    * 根据文件名获取文件地址  
    *  
    * @param fileName  
    * @param bucketName  
    * @return 文件地址  
    */  
    public String preview(String fileName, String bucketName) {  
        try {  
            GetPresignedObjectUrlArgs presignedObjectUrlArgs = new GetPresignedObjectUrlArgs().builder()  
                .bucket(bucketName)  
                .object(fileName)  
                .method(Method.GET)  
                .build();  
            return minioClient.getPresignedObjectUrl(presignedObjectUrlArgs);  
        } catch (Exception ex) {  
            log.info("preview error: {}", ex.getMessage());  
            return null;  
        }  
    }
  • 获取Bucket中所有Object
    @Autowired  
    private MinioClient minioClient;
    
    /**  
    * 获取Bucket中所有文件对象  
    *  
    * @param bucketName  
    * @return  
    */  
    public List<Item> listObjects(String bucketName) {  
        Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());  
        List<Item> items = new ArrayList<>();  
        results.forEach(item -> {  
        try {  
            items.add(item.get());  
        } catch (Exception ex) {  
            log.info("listObjects error: {}", ex.getMessage());  
        }  
        });  
        return items;  
    }
  • 删除文件
    @Autowired  
    private MinioClient minioClient;
    
    /**  
    * 删除文件  
    *  
    * @param fileName  
    * @param bucketName  
    * @return  
    */  
    public boolean removeFile(String fileName, String bucketName) {  
        try {  
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());  
        } catch (Exception ex) {  
            log.info("removeFile error: {}", ex.getMessage());  
            return false;  
        }  
        return true;  
    }

5、编写Service层和Controller层

FileService接口自行补充

@Slf4j  
@Service  
public class MinioFileServiceImpl implements FileService {  
    @Value("${minio.bucketName}")  
    private String bucketName;  
    @Autowired  
    private MinioUtils minioUtils;  

    @Override  
    public CommonResult upload(MultipartFile file) {  
        if (file.isEmpty()) {  
            return CommonResult.fail("文件不可为空");  
        }  
        String fileName = minioUtils.uploadFile(file, bucketName);  
        return CommonResult.success(fileName);  
    }  

    @Override  
    public void download(String fileName, HttpServletResponse res) {  
        ObjectMapper objectMapper = new ObjectMapper();  
        try(ServletOutputStream outputStream = res.getOutputStream()) {  
            if (StringUtils.isEmpty(fileName)) {  
            outputStream.write(objectMapper.writeValueAsBytes(CommonResult.fail("文件名不可为空")));  
        }  
            minioUtils.download(fileName, bucketName, res);  
        } catch (IOException ex) {  
            log.warn("download file error: {}", ex.getMessage());  
        }  
    }  

    @Override  
    public CommonResult delete(String fileName) {  
        if (StringUtils.isEmpty(fileName)) {  
            return CommonResult.fail("文件名不可为空");  
        }  
        minioUtils.removeFile(fileName, bucketName);  
        return CommonResult.success();  
    }  

    @Override  
    public CommonResult review(String fileName) {  
        if (StringUtils.isEmpty(fileName)) {  
            return CommonResult.fail("文件名不可为空");  
        }  
        String preview = minioUtils.preview(fileName, bucketName);  
        return CommonResult.success(preview);  
    }  
}
@RequestMapping("/file")  
@Controller  
public class FileController {  
    @Autowired  
    private FileService fileService;  

    @ResponseBody  
    @PostMapping("/upload")  
    public CommonResult upload(MultipartFile file) {  
        return fileService.upload(file);  
    }  

    @PostMapping("/download")  
    public void download(@RequestParam("fileName") String fileName, HttpServletResponse res) {  
        fileService.download(fileName, res);  
    }  

    @ResponseBody  
    @PostMapping("/delete")  
    public CommonResult delete(@RequestParam("fileName") String fileName) {  
        return fileService.delete(fileName);  
    }  

    @ResponseBody  
    @PostMapping("/preview")  
    public CommonResult preview(@RequestParam("fileName") String fileName) {  
        return fileService.review(fileName);  
    }  
}