Minio实现分布式存储

什么是MinIO?

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

MinIO是高性能对象存储,什么是对象存储(Object Storage Service),对象存储是支持海量用户远程访问的无限容量廉价存储系统,既然是存储系统。

它由桶(bucket,对应Windows下的文件夹),组成目录结构,桶中直接存放对象(Object,对应Windwos下的文件),桶中不能再创建通,但是要能创建文件夹。

怎么用?

下载MinIO

访问官网:https://docs.min.io/

进入下载页面点击windows

点击下载服务端

将MinIO.exe 拷贝到自己的目录下去,并创建一个data目录

通过命令行启动Minio

minio server ./data

启动完成后,可以看到访问的路径http://127.0.0.1:9000

使用提供的账号密码进行登录

账号:minioadmin

密码:minioadmin

说明minio已经正常启动了

MioIO的使用

由于我们已经了解到MinIO是由桶(bucket)组成的,相当于是文件夹

对应的应该先要创建通bucket

创建桶

创建名叫huike-crm的桶

创建好桶之后看到如下内容

先尝试通过MinIO的控制台上传一个文件

上传一个java.png

点击上传的文件并生成分享的链接

点击copy拷贝生成分享的url

http://172.16.17.121:9000/huike-crm/java.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=KGWTGVTCK8G5MV01HQ5A%2F20220318%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220318T081644Z&X-Amz-Expires=604800&X-Amz-Security-Token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJLR1dUR1ZUQ0s4RzVNVjAxSFE1QSIsImV4cCI6MTY0NzU5MzU4MSwicGFyZW50IjoibWluaW9hZG1pbiJ9.BdsOeJp6v1zPUPTH79Eb4u_Mf_f8eG0Pvwd8IewMdI1mJGSzqYnJxaP3SKV_-c4AtoIYBJBT_4zh2N3AYYFOUw&X-Amz-SignedHeaders=host&versionId=null&X-Amz-Signature=c3205a0361341505aa4107655716c4e71a47dd40606bd4e03033138fbd6b7c96

在浏览器里访问,可以看到上传的图片

可以看到图片里的内容,证明minio已经可以正常使用了

但是,存在一些问题,我们生成一个分享url的时候发现有一个有效期

也就是说我们生成的分享的url的有效期只有7天,过了这7天以后再想通过这个url来进行访问就会有问题

我们能否直接将上传上来的文件暴露出去,而不再需要通过分享的这个url来进行访问呢?

如果现在我们要直接访问我们的MinIO里的文件要如何访问

我们应该直接访问 Minio的ip+端口/桶名称/文件名

http://172.16.17.121:9000/huike-crm/java.png

我们在浏览器中尝试了一下

看到返回的数据的内容,没有权限

注意这里的权限的配置是在桶这一级别的

添加读取readOnly对应的权限是*即拥有所有权限

然后重新范围java.png

http://172.16.17.121:9000/huike-crm/java.png

到此对minio的配置全部结束

现在与java集成

参考官网

导入maven

<dependency>
    <groupId>io.minio</groupId>

    <artifactId>minio</artifactId>

    <version>8.3.7</version>

</dependency>

FileUploader.java

import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.UploadObjectArgs;
import io.minio.errors.MinioException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class FileUploader {
  public static void main(String[] args)
      throws IOException, NoSuchAlgorithmException, InvalidKeyException {
    try {
      // Create a minioClient with the MinIO server playground, its access key and secret key.
      MinioClient minioClient =
          MinioClient.builder()
              .endpoint("https://play.min.io")
              .credentials("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG")
              .build();

      // Make 'asiatrip' bucket if not exist.
      boolean found =
          minioClient.bucketExists(BucketExistsArgs.builder().bucket("asiatrip").build());
      if (!found) {
        // Make a new bucket called 'asiatrip'.
        minioClient.makeBucket(MakeBucketArgs.builder().bucket("asiatrip").build());
      } else {
        System.out.println("Bucket 'asiatrip' already exists.");
      }

      // Upload '/home/user/Photos/asiaphotos.zip' as object name 'asiaphotos-2015.zip' to bucket
      // 'asiatrip'.
      minioClient.uploadObject(
          UploadObjectArgs.builder()
              .bucket("asiatrip")
              .object("asiaphotos-2015.zip")
              .filename("/home/user/Photos/asiaphotos.zip")
              .build());
      System.out.println(
          "'/home/user/Photos/asiaphotos.zip' is successfully uploaded as "
              + "object 'asiaphotos-2015.zip' to bucket 'asiatrip'.");
    } catch (MinioException e) {
      System.out.println("Error occurred: " + e);
      System.out.println("HTTP trace: " + e.httpTrace());
    }
  }
}

具体实现:

文件上传实现类:

@Service
@Slf4j
public class SysFileServiceImpl implements ISysFileService{

    @Autowired
    MinioConfig minioConfig;

    /**
     * 文件上传至Minio
     * 使用try catch finally进行上传
     * finally里进行资源的回收
     */
    @Override
    public AjaxResult upload(MultipartFile file) {
        InputStream inputStream = null;
        //创建Minio的连接对象
        MinioClient minioClient = getClient();
        String bucketName = minioConfig.getBucketName();
        try {
            inputStream = file.getInputStream();
            //判断文件存储的桶是否存在 如果桶不存在就创建桶
            isBucket(minioClient, bucketName);
            //操作文件(构建文件目录:2024/02/22/550e8400e29b41d4a716446655440000example.pdf)
            String fileName = file.getOriginalFilename();
            String fileNameFinal = new SimpleDateFormat("yyyy/MM/dd/").format(new Date()) //获取当前日期格式化为路径格式
            + UUID.randomUUID().toString().replaceAll("-", "") //去掉UUID生成的字符串中的 -
            + fileName.substring(fileName.lastIndexOf(".")); //拼接原文件的后缀 .pgf
            //文件上传
            //由于使用的是SpringBoot与之进行集成 上传的时候拿到的是MultipartFile 需要通过输入输出流的方式进行添加
            PutObjectArgs objectArgs = PutObjectArgs.builder()
            .object(fileNameFinal)
            .bucket(bucketName)
            .contentType(file.getContentType())
            .stream(file.getInputStream(), file.getSize(), -1)
            .build();
            minioClient.putObject(objectArgs);
            //封装访问的url给前端
            AjaxResult ajax = AjaxResult.success();
            ajax.put("fileName","/" + bucketName + "/" + fileNameFinal);
            //拼接url
            ajax.put("url",minioConfig.getEndpoint() + ":" + minioConfig.getPort() + "/" + minioConfig.getBucketName() + "/" + fileNameFinal);
            return ajax;
        }catch(Exception e){
            e.printStackTrace();
            return AjaxResult.error("上传失败");
        }finally {
            //防止内存泄漏
            if (inputStream != null) {
                try {
                    inputStream.close(); // 关闭流
                } catch (IOException e) {
                    log.debug("inputStream close IOException:" + e.getMessage());
                }
            }
        }
    }

    /**
     * 判断桶是否存在,不存在则创建
     * @param minioClient
     * @param bucketName
     * @throws ErrorResponseException
     * @throws InsufficientDataException
     * @throws InternalException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws ServerException
     * @throws XmlParserException
     */
    private static void isBucket(MinioClient minioClient, String bucketName) throws ErrorResponseException, InsufficientDataException, InternalException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException {
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        if (!found){
            //如果桶不存在,则创建桶
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
       }
    }


    /**
     * 免费提供一个获取Minio连接的方法
     * 获取Minio连接
     * @return
     */
    private MinioClient getClient(){
       MinioClient minioClient =
             MinioClient.builder()
                   .endpoint("http://"+minioConfig.getEndpoint()+":"+ minioConfig.getPort())
                   .credentials(minioConfig.getAccessKey(),minioConfig.getSecretKey())
                   .build();
       return minioClient;
    }
}

文件上传配置类:

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

    private final static String HTTP = "http://";

    //endPoint是一个URL,域名,IPv4或者IPv6地址
    private String endpoint;

    //TCP/IP端口号
    private int port;

    //accessKey类似于用户ID,用于唯一标识你的账户
    private String accessKey;

    //secretKey是你账户的密码
    private String secretKey;

    //如果是true,则用的是https而不是http,默认值是true
    private Boolean secure;

    //默认存储桶
    private String bucketName;
}

配置文件:

# Miniio配置
minio:
  endpoint: 127.0.0.1
  port: 9000
  accessKey: minioadmin
  secretKey: minioadmin
  secure: false
  bucketName: "huike-crm"
  configDir: "/data/excel"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leighteen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值