MinIo新旧版本工具类和部署文档

work文档格式,后面再调整

MinIO 使用文档
下载安装
官网下载地址:https://min.io/download

注:本文档使用的目录和ip要根据自己项目设置
单机部署
1.创建目录
1.1创建保存minio目录
mkdir -p /minio
1.2创建启动目录
mkdir -p /minio/bin/
1.3创建minio bucket目录,即上传文件保存目录
mkdir -p /minio/data

2.创建启动脚本
start.sh
#!/bin/bash
#设置用户名和密码
export MINIO_ACCESS_KEY=panys
export MINIO_SECRET_KEY=panys123456
#设置端口 --address ip:port
#后台启动
nohup /minio/minio server --address 192.168.201.149:9002 /minio/data/ > /minio/logs/minio.log 2>&1 &


3.创建停止脚本
#!/bin/bash
#停止 stop
ps -ef | grep -w minio | grep -v grep | awk '{print $2}'|xargs kill -9


4.授权
4.1授权minio文件
chmod +x minio
4.2给脚本start.sh和stop.sh授权
chmod+x start.sh stop.sh
5.启动测试
运行启动脚本
./minio/bin/start.sh
在浏览器上输入访问地址http://192.168.201.149:9002,测试创建bucket和上传文件

显示上图代表单机部署成功

集群部署
因为官方推荐集群部署需要四个节点,所以本文档使用两台机器,每台机器两个磁盘模式部署
192.168.201.149  /minio/data   /minio/data2
192.168.201.150  /minio/data   /minio/data2
   
1.创建目录
1.1创建保存minio目录
mkdir -p /minio
上传下载的minio文件到minio目录
1.2创建启动目录
mkdir -p /minio/bin/
1.3创建minio bucket目录
即上传文件保存目录,两台机器都需要创建
mkdir -p /minio/{data,data2}
2.创建启动脚本
start.sh
#!/bin/bash
#设置用户名和密码
export MINIO_ACCESS_KEY=panys
export MINIO_SECRET_KEY=panys123456
#修改访问 --address ip:port
#后台启动
nohup /minio/minio server --address 0.0.0.0:9002 http://192.168.201.149/minio/data http://192.168.201.149/minio/data2 http://192.168.201.150/minio/data http://192.168.201.150/minio/data2 > /minio/logs/minio.log 2>&1 &


3.创建停止脚本
stop.sh
#!/bin/bash
#停止 stop
ps -ef | grep -w minio | grep -v grep | awk '{print $2}'|xargs kill -9

4.授权
两台机器都需要执行
4.1授权minio文件
chmod +x minio
4.2给脚本start.sh和stop.sh授权
chmod+x start.sh stop.sh

5.启动测试
两台机器运行启动脚本
./minio/bin/start.sh
在浏览器上输入访问地址http://192.168.201.149:9002,测试创建bucket和上传文件

在浏览器上输入访问地址http://192.168.201.150:9002,如果有相同的文件则集群部署minio成功。
Nginx代理
minio集群部署,提供统一访问路径,可以使用nginx配置负载均衡
如下:
upstream minio{
	server 192.168.201.149:9002;
	server 192.168.201.150:9002;
}
server {
	listen 9002;
	server_name minio;
	location / {
		proxy_set_header Host $http_host;
		proxy_set_header X-Forwarded-For $remote_addr;
		client_body_buffer_size 10M;
		client_max_body_size 10G;
		proxy_buffers 1024 4k;
		proxy_read_timeout 300;
		proxy_next_upstream error timeout http_404;
		proxy_pass http://minio;
	}
}

整合springboot 2.x API
Java client API 官方文档
https://docs.min.io/docs/java-client-quickstart-guide.html

说明:minio从7.0.2版本后开始变化,API有所区别,规范了参数

配置文件yaml
# minio 配置,endpoint访问路径,accessKey 用户名,secretKey 密码,bucketName 存储桶
min:
  io:
    endpoint: http://192.168.201.148:9002
    accessKey: aaa
secretKey: aaa123456
bucketName: test


旧版
引入maven文件
旧版:
<dependency>
	<groupId>io.minio</groupId>
	<artifactId>minio</artifactId>
	<version>7.0.2</version>
</dependency>
新版:
<dependency>
	<groupId>io.minio</groupId>
	<artifactId>minio</artifactId>
	<version>8.2.1</version>
</dependency>

工具类
MinIoProperties
package cn.emd.platform.common.file.config;

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

/**
 * MinIo实体参数类
 *
 * @author pan
 * @date 2021/4/26
 */
@Data
@Component
@ConfigurationProperties(prefix = "min.io")
public class MinIoProperties {

    /**
     * 访问地址
     */
    private String endpoint;

    /**
     * 用户名
     */
    private String accessKey;

    /**
     * 密码
     */
    private String secretKey;

    /**
     * 存储桶
     */
    private String bucketName="pan";

}


特殊参数说明
objectName存储桶的文件名,可以是文件,也可以是文件夹+文件
例如:Entity.vm或者pan/Entity.vm
filename 文件所在地址,上传文件时文件所在位置地址
例如:D://Entity.vm
fileName 文件保存地址,下载时保存文件位置地址
例如:D://pan/entity.vm 

旧版工具类
MinIoUtils

package cn.emd.platform.common.file.util;

import cn.emd.platform.common.core.exception.DynamicException;
import cn.emd.platform.common.file.config.MinIoProperties;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.minio.errors.*;

import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.InputStream;

/**
 * MinIo工具类
 *
 * @author pan
 * @date 2021/4/25
 */
@Component
@Configuration
@EnableConfigurationProperties(MinIoProperties.class)
public class MinIoUtils {

    private MinIoProperties minIoProperties;
    private MinioClient minioClient;

    public MinIoUtils(MinIoProperties minIoProperties){
        this.minIoProperties=minIoProperties;
    }

    @PostConstruct
    public void init(){
        try {
            minioClient=new MinioClient(minIoProperties.getEndpoint(),
                    minIoProperties.getAccessKey(),
                    minIoProperties.getSecretKey());
            //创建一个默认的bucket
            boolean found =this.bucketExists(minIoProperties.getBucketName());
            if (!found) {
                this.makeBucket(minIoProperties.getBucketName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断是否存在 bucket
     * @param bucketName 存储桶
     * @return 存在true,不存在false
     */
    public Boolean bucketExists(String bucketName){

        try {
            return minioClient.bucketExists(bucketName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 创建bucket
     *
     * @author pan
     * @date 2021/4/26
     */
    public void makeBucket(String bucketName){

        try {
            if(bucketExists(bucketName)){
                throw new DynamicException(bucketName+"已存在");
            }
            minioClient.makeBucket(bucketName);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用默认的存储桶bucket
     *
     * @author pan
     * @date 2021/4/26
     */
    public String useDefaultBucket(String bucketName){
        if(StringUtils.isBlank(bucketName)){
            bucketName=minIoProperties.getBucketName();
        }
        return bucketName;
    }

    /**
     * 上传文件(地址方式)
     * @param bucketName 存储桶名称
     * @param objectName 保存在存储桶的文件
     * @param filename 文件+路径
     * @return 文件保存位置
     */
    @SneakyThrows
    public String uploadFile(String bucketName,String objectName,String filename){
        //如果存储桶为空,则使用默认的
        bucketName = useDefaultBucket(bucketName);
        if (!this.bucketExists(bucketName)) {
            throw new DynamicException(bucketName + "存储桶不存在");
        }
        minioClient.putObject(bucketName,objectName,filename,null);
        return objectName;
    }

    /**
     * 上传文件
     * @param bucketName 存储桶名称
     * @param objectName 保存在存储桶的文件
     * @param multipartFile 文件流
     * @return 文件保存位置
     */
    @SneakyThrows
    public String uploadFile(String bucketName, String objectName, MultipartFile multipartFile){
        //如果存储桶为空,则使用默认的
        bucketName = useDefaultBucket(bucketName);
        if (!this.bucketExists(bucketName)) {
            throw new DynamicException(bucketName + "存储桶不存在");
        }
        InputStream inputStream=multipartFile.getInputStream();
        PutObjectOptions putObjectOptions=new PutObjectOptions(multipartFile.getSize(),-1L);
        minioClient.putObject(bucketName,objectName,inputStream,putObjectOptions);
        return objectName;
    }

    /**
     * 删除文件
     * @param bucketName 存储桶名称
     * @param objectName 保存在存储桶的文件
     * @return 文件保存位置
     */
    @SneakyThrows
    public String deleteFile(String bucketName, String objectName){
        bucketName = useDefaultBucket(bucketName);
        if (!this.bucketExists(bucketName)) {
            throw new DynamicException(bucketName + "存储桶不存在");
        }
        minioClient.removeObject(bucketName,objectName);
        return objectName;
    }

    /**
     * 下载文件
     * @param bucketName 存储桶名称
     * @param objectName 保存在存储桶的文件
     * @param fileName 文件保存位置
     * @return 文件保存位置
     */
    @SneakyThrows
    public String downloadFile(String bucketName, String objectName,String fileName){
        bucketName = useDefaultBucket(bucketName);
        if (!this.bucketExists(bucketName)) {
            throw new DynamicException(bucketName + "存储桶不存在");
        }
        minioClient.getObject(bucketName,objectName,fileName);
        return fileName;
    }

    /**
     * 下载文件
     * @param bucketName 存储桶名称
     * @param objectName 保存在存储桶的文件
     * @return 文件保存位置
     */
    @SneakyThrows
    public InputStream downloadFile(String bucketName, String objectName){
        bucketName = useDefaultBucket(bucketName);
        if (!this.bucketExists(bucketName)) {
            throw new DynamicException(bucketName + "存储桶不存在");
        }
        return minioClient.getObject(bucketName,objectName);
    }
}


新版工具类
MinIoUtil
package cn.emd.platform.common.file.util;

import cn.emd.platform.common.core.exception.DynamicException;
import cn.emd.platform.common.file.config.MinIoProperties;
import io.minio.*;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.InputStream;

/**
 * MinIo工具类
 *
 * @author pan
 * @date 2021/4/27
 */
@Component
@Configuration
@EnableConfigurationProperties(MinIoProperties.class)
public class MinIoUtil {

    private MinIoProperties minIoProperties;
    private MinioClient minioClient;

    public MinIoUtil(MinIoProperties minIoProperties){
        this.minIoProperties=minIoProperties;
    }

    @PostConstruct
    public void init(){

        minioClient=MinioClient.builder()
                .endpoint(minIoProperties.getEndpoint())
                .credentials(minIoProperties.getAccessKey(),minIoProperties.getSecretKey())
                .build();
        //创建默认一个bucket,即存储桶
        try {
            boolean found =this.bucketExists(minIoProperties.getBucketName());
            if (!found) {
                this.makeBucket(minIoProperties.getBucketName());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
      * 判断是否存在 bucket
      * @param bucketName 存储桶
      * @return 存在true,不存在false
      */
    public Boolean bucketExists(String bucketName){

        try {
            return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 创建bucket
     *
     * @author pan
     * @date 2021/4/26
     */
    public void makeBucket(String bucketName){

        try {
            if(this.bucketExists(bucketName)){
                throw new DynamicException(bucketName+"已存在");
            }
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用默认的存储桶bucket
     *
     * @author pan
     * @date 2021/4/26
     */
    public String useDefaultBucket(String bucketName){
        if(StringUtils.isBlank(bucketName)){
            bucketName=minIoProperties.getBucketName();
        }
        return bucketName;
    }

    /**
     * 上传文件(浏览器方式)
     *
     * @param bucketName    存储桶名称
     * @param objectName    保存在存储桶的文件
     * @param multipartFile 文件流
     * @return 文件保存位置
     */
    @SneakyThrows
    public String uploadFile(String bucketName, String objectName, MultipartFile multipartFile) {
        //如果存储桶为空,则使用默认的
        bucketName=useDefaultBucket(bucketName);
        if (!this.bucketExists(bucketName)) {
            throw new DynamicException(bucketName + "存储桶不存在");
        }
        InputStream inputStream = multipartFile.getInputStream();
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .stream(inputStream,multipartFile.getSize(),-1L)
                .build());
        return objectName;
    }

    /**
     * 上传文件(地址方式)
     *
     * @param bucketName    存储桶名称
     * @param objectName    保存在存储桶的文件
     * @param filename 文件地址
     * @return 文件保存位置
     */
    @SneakyThrows
    public String uploadFile(String bucketName, String objectName, String filename) {
        //如果存储桶为空,则使用默认的
        bucketName = useDefaultBucket(bucketName);
        if (!this.bucketExists(bucketName)) {
            throw new DynamicException(bucketName + "存储桶不存在");
        }
        minioClient.uploadObject(UploadObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .filename(filename)
                .build()
        );
        return objectName;
    }

    /**
     * 下载文件
     *
     * @param bucketName 存储桶名称
     * @param objectName 保存在存储桶的文件
     * @param fileName   文件保存位置
     * @return 文件保存位置
     */
    @SneakyThrows
    public String downloadFile(String bucketName, String objectName, String fileName) {
        bucketName = useDefaultBucket(bucketName);
        if (!this.bucketExists(bucketName)) {
            throw new DynamicException(bucketName + "存储桶不存在");
        }
        minioClient.downloadObject(DownloadObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .filename(fileName)
                .build()
        );
        return fileName;
    }

    /**
     * 下载文件
     *
     * @param bucketName 存储桶名称
     * @param objectName 保存在存储桶的文件
     * @return 文件流
     */
    @SneakyThrows
    public InputStream downloadFile(String bucketName, String objectName) {
        bucketName = useDefaultBucket(bucketName);
        if (!this.bucketExists(bucketName)) {
            throw new DynamicException(bucketName + "存储桶不存在");
        }
        InputStream inputStream=minioClient.getObject(GetObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build()
        );
        return inputStream;
    }


    /**
     * 删除文件
     *
     * @param bucketName 存储桶名称
     * @param objectName 保存在存储桶的文件
     * @return 文件保存位置
     */
    @SneakyThrows
    public String deleteFile(String bucketName, String objectName) {
        bucketName = useDefaultBucket(bucketName);
        if (!this.bucketExists(bucketName)) {
            throw new DynamicException(bucketName + "存储桶不存在");
        }
        minioClient.removeObject(RemoveObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build());
        return objectName;
    }

}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你可以使用以下的Python代码来创建一个Minio上传图片的工具类: ```python from minio import Minio from minio.error import ResponseError class MinioUploader: def __init__(self, endpoint, access_key, secret_key, bucket_name): self.endpoint = endpoint self.access_key = access_key self.secret_key = secret_key self.bucket_name = bucket_name def upload_image(self, file_path, object_name): try: minio_client = Minio(self.endpoint, access_key=self.access_key, secret_key=self.secret_key, secure=False) # 检查bucket是否存在,不存在则创建 if not minio_client.bucket_exists(self.bucket_name): minio_client.make_bucket(self.bucket_name) # 上传图片 minio_client.fput_object(self.bucket_name, object_name, file_path) return True, "Image uploaded successfully" except ResponseError as err: return False, f"Error uploading image: {err}" ``` 使用时,你需要提供Minio服务的endpoint、access_key、secret_key以及bucket_name。然后,你可以调用`upload_image`方法来上传图片。该方法接收两个参数:`file_path`表示本地图片文件的路径,`object_name`表示在Minio中保存的对象名称。 以下是一个使用示例: ```python minio_uploader = MinioUploader(endpoint='minio.example.com', access_key='your-access-key', secret_key='your-secret-key', bucket_name='your-bucket-name') success, message = minio_uploader.upload_image('/path/to/image.jpg', 'image.jpg') if success: print(message) else: print(f"Error: {message}") ``` 请确保已经安装了`minio`库,可以使用`pip install minio`来进行安装。此外,根据你实际的Minio配置,需要修改代码中的相关参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小生有礼了哈

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

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

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

打赏作者

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

抵扣说明:

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

余额充值