Minio 入门

安装

Docker

docker run  --name minio \
-d --restart=always \
-p 9000:9000 \
-p 9001:9001 \
--network tool-net --network-alias minio \
-e "MINIO_ACCESS_KEY=admin" \
-e "MINIO_SECRET_KEY=admin123456" \
-v minio_data:/data \
-v min_config:/root/.minio \
minio/minio server /data --console-address ":9001"
  • 注意:

    1. --console-address 当前最新版必须指定控制台端口(浏览器页面访问端口),如果不指定,将会随机生成端口,不方便服务器开启防火墙
    2. Minio 默认api addres 的端口是9000,浏览器访问9000端口时,会跳转到控制台端口--console-address
    3. 一定要将Minio的数据目录挂载到主机上,防止删除容器时,删除了储存的数据

控制台

进入控制台可以通过9000端口,他会自动跳转到控制台的9001端口,也可以直接通过9001端口进入控制台

登录

控台登录账户和密码是Docker 启动时的MINIO_ACCESS_KEY参数和MINIO_SECRET_KEY参数

Minio 入门_第1张图片

桶(Bucket):Minio 通过桶去存储文件,存储文件时需要指定目标桶才可以存储,

创建桶

点击Bucket->create bucket

Minio 入门_第2张图片

配置桶

1. 基础信息

右侧有关于配置信息的解释

  • Bucket Name: 桶名
  • Version:开启统一对象多版本
  • Object locking:对象锁:防止对象被删除,如果不设置Retention,那么文件将不能被删除
  • Quota:配额,限制桶内的对象数量
  • Retention:保留策略,设置文件再桶内存活的周期,开启后Object locking会自动开启,因为文件保留期间,对象是禁止删除的
    • Model:策略模式:1. Compliance:在Validity天后被删除 2. Governance 在Validity天后删除在生命周期内未操作的对象
    • Validity:生命周期:对象至少存活多少天

Minio 入门_第3张图片

2. 桶内对象的操作策略

点击Bucket-->Manage--> Access Rules

Minio 入门_第4张图片

上传后的对象名格式:[Rule alias]_[Object Name].[文件后缀]

  • Prefix:Rule 别名
  • Access:决策

Minio 入门_第5张图片

身份 Identity

身份管理

账户 Users

创建、管理Minio账户

账户组 Groups

对Minio用户进行分组

服务账户 Services Accounts

创建、管理服务账户
这里创建的账户,主要用于开发,也是最常用的

Minio 入门_第6张图片

Create Service Account

  1. 点击create service account,创建Service Account

Minio会自动创建键账户和密码,如果开发这需要配置使用权限,可开启下方的Restrict beyond user policy

  1. 点击create,会提示你保存密钥信息,个人建议下载密钥i信息,因为密钥是随机值,不方便记忆
    Minio 入门_第7张图片

使用

Spring boot

依赖

<dependency>
	<groupId>io.miniogroupId>
    <artifactId>minioartifactId>
    <version>8.2.1version>
dependency>

配置类

MinIOProperties.java

Minio 参数 Properties类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "minio")
public class MinIOProperties {

    /**
     * 连接url
     */
    private String endpoint;
    /**
     *  Service Account——accesskey
     */
    private String accessKey;
    /**
     * Service Account——secretKey
     */
    private String secretKey;

    /**
     * 桶
     */
    private String bucket;

    /**
     * 分片大小
     */
    private long partSize=5 * 1024 * 1024;
}
MinIOHelper,java

Minio工具类,用于编写操作Minio的具体方法
该类在AutoConfig类中已注入到IOC容器中,方便开发者在service或controller中调用

import cn.hutool.core.util.ObjectUtil;
import io.minio.*;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileNotFoundException;

public class MinIOHelper {

    @Autowired
    private MinioClient client;

    @Autowired
    private MinIOProperties properties;

    /**
     * 创建桶
     *
     * @param bucketName 通名称
     */
    @SneakyThrows
    public void createBucket(String bucketName) {
        BucketExistsArgs bucket = BucketExistsArgs.builder().bucket(bucketName).build();
        if (!client.bucketExists(bucket)) {
            MakeBucketArgs make = MakeBucketArgs.builder().bucket(bucketName).build();
            client.makeBucket(make);
        }
    }

    /**
     * 上传文件
     *
     * @param file       文件
     * @param bucketName 存储桶
     * @return
     */
    public String uploadFile(MultipartFile file, String bucketName, FileRule rule) throws FileNotFoundException {

        // 判断上传文件是否为空
        if (ObjectUtil.isEmpty(file) || 0 == file.getSize()) {
            throw new FileNotFoundException();
        }

        //检查桶名
        if (ObjectUtil.isEmpty(bucketName)) {
            bucketName = properties.getBucket();
            if (ObjectUtil.isEmpty(bucketName)) {
                throw new MinioUploadExecption("Bucket 必填");
            }
        }

        if (ObjectUtil.isEmpty(rule)) {
            rule = FileRule.READ_WRITE;
        }

        try {
            // 判断存储桶是否存在
            createBucket(bucketName);
            // 文件名
            String originalFilename = file.getOriginalFilename();
            // 新的文件名 = 存储桶名称_时间戳.后缀名
            String fileName = rule.getLabel() + "_" + System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf("."));

            // 开始上传
            PutObjectArgs build = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .contentType(file.getContentType())
                    .stream(file.getInputStream(), file.getSize(), properties.getPartSize())
                    .build();

            ObjectWriteResponse response = client.putObject(build);

            return bucketName + "/" + fileName;
        } catch (Exception e) {
            throw new MinioUploadExecption("上传失败");
        }
    }
}
FileRule.java

该枚举类实现的是Bucket Access Rules配置内容,方便开发者调用,不在用于记忆前缀

public enum FileRule {
    WRITE_ONLY(0, "w"),
    READ_ONLY(1, "r"),
    READ_WRITE(2,"r-w");

    private Integer value;

    private String label;

    FileRule(Integer value, String label) {
        this.value = value;
        this.label = label;
    }

    public Integer getValue() {
        return value;
    }

    public String getLabel() {
        return label;
    }
}
EnableOSS.java

Minio启动注解
将该类配置在对应服务的启动类上,即可
服务启动时spring 会自动去寻找@Import({MinIOAutoCondig.class})的自动配置类,从而实现自动配置

import org.springframework.context.annotation.Import;

import java.lang.annotation.*;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({MinIOAutoCondig.class})
public @interface EnableOSS {
}
MinIOAutoCondig.java

Minio 自动配置类
因为Minio 本身就是未分布式微服务而设计的,所以必然存在多模块,而为了调用方便,所以本文使用启动注解加自动配置类的方式调用Minio

import cn.hutool.core.util.ObjectUtil;
import io.minio.MinioClient;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@ConditionalOnClass({MinioClient.class})
@Configuration
@EnableConfigurationProperties({MinIOProperties.class})
public class MinIOAutoCondig {

    @Autowired
    private MinIOProperties minIOProperties;

    private MinioClient client;

    @Bean
    public MinioClient minioClient() {
        if (ObjectUtil.isEmpty(minIOProperties.getEndpoint())) {
            throw new BeanCreationException("minio.endpoint don't null");
        }

        if (ObjectUtil.isEmpty(minIOProperties.getAccessKey())) {
            throw new BeanCreationException("minio.access-key don't null");
        }

        if (ObjectUtil.isEmpty(minIOProperties.getSecretKey())) {
            throw new BeanCreationException("minio.secret-key don't null");
        }

        client= MinioClient.builder().endpoint(minIOProperties.getEndpoint()).credentials(minIOProperties.getAccessKey(), minIOProperties.getSecretKey()).build();
        return client;
    }

    @Bean
    public MinIOHelper minIOHelper(){
        return new MinIOHelper();
    }
}

调用

Properties

minio.access-keyminio.secret-key分别对应的是Services Accounts 中创建的账户

minio.endpoint=http://xx.xx.xx.xx:9000
minio.bucket=client
minio.access-key=gutgSnXxxxxH2zgxxx
minio.secret-key=EOiOz9KFxxxxmaC8uGLxxxxQlJINVPSxxx
Controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.cxjfun.jdoc.client.server.vo.UploadFile;
import top.cxjfun.jdoc.common.CustomException;
import top.cxjfun.jdoc.common.db.oss.MinIOHelper;

import javax.servlet.http.HttpServletRequest;
import java.io.FileNotFoundException;

@RestController
@RequestMapping("/file")
public class FileController {

    @Autowired
    private MinIOHelper minIOHelper;

    @PostMapping("/upload")
    @ResponseBody
    public String upload(MultipartFile file, HttpServletRequest request) {
        try {
            String filePath = minIOHelper.uploadFile(file, null, null);
            return filePath;
        } catch (FileNotFoundException e) {
            throw new CustomException("FILE_NOT_FOUND", "文件未找到");
        }
    }
}

FAQ

io.minio.S3Base.(S3Base.java:105)

	An attempt was made to call a method that does not exist. The attempt was made from the following location:

    io.minio.S3Base.<clinit>(S3Base.java:105)

The following method did not exist:

    okhttp3.RequestBody.create([BLokhttp3/MediaType;)Lokhttp3/RequestBody;

The method's class, okhttp3.RequestBody, is available from the following locations:

    jar:file:/D:/repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar!/okhttp3/RequestBody.class

The class hierarchy was loaded from the following locations:

    okhttp3.RequestBody: file:/D:/repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of okhttp3.RequestBody
问题原因

Spring boot 和minio 依赖冲突产生的原因是因为spring boot 的okhttp 和minio 的okhttp冲突

解决办法

降低minio版本:8.3.0 —> 8.2.1

你可能感兴趣的:(TOOLS,策略模式,java,docker)