ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用MinIO搭建对象存储服务

2022-05-20 20:35:13  阅读:222  来源: 互联网

标签:存储 minio springframework String import org 搭建 com MinIO


1.MinIO是什么?

  • MinIO 是一款高性能、分布式的对象存储系统. 它是一款软件产品, 可以100%的运行在标准硬件。即X86等低成本机器也能够很好的运行MinIO。
  • MinIO与传统的存储和其他的对象存储不同的是:它一开始就针对性能要求更高的私有云标准进行软件架构设计。因为MinIO一开始就只为对象存储而设计。所以他采用了更易用的方式进行设计,它能实现对象存储所需要的全部功能,在性能上也更加强劲,它不会为了更多的业务功能而妥协,失去MinIO的易用性、高效性。 这样的结果所带来的好处是:它能够更简单的实现局有弹性伸缩能力的原生对象存储服务。
  • MinIO在传统对象存储用例(例如辅助存储,灾难恢复和归档)方面表现出色。同时,它在机器学习、大数据、私有云、混合云等方面的存储技术上也独树一帜。当然,也不排除数据分析、高性能应用负载、原生云的支持。

之前我使用的是阿里云OSS,想了解阿里云OSS的小伙伴参考SpringBoot整合阿里云OSS

2.我这里使用的是docker安装方式,使用的前提是小伙伴你已经安装好了一个docker了,关于docker的具体使用可以参考docker的具体使用

image

3.使用步骤

(1)下载镜像,下载可能有点慢大家等待一下或者配置一下阿里云镜像加速器

docker run -d -p 9000:9000 -p 9001:9001 --name minio -e MINIO_ACCESS_KEY=qbb -e MINIO_SECRET_KEY=startqbb -v /opt/minio/data:/data -v /opt/minio/config:/root/.minio minio/minio server /data --console-address ":9000" --address ":9001"

  • MINIO_ACCESS_KEY:指定的是"用户名",可以这么理解,后面我们文件上传需要使用
  • MINIO_SECRET_KEY:指定的是"密码",可以这么理解,后面我们文件上传需要使用

image

下载并运行完成

image

注意:
  • 有可能下载的过程中会出现如下图,minio容器并没有正常启动
    docker ps -a:查看所有容器
    image

  • 我们可以使用docker logs 容器ID(CONTAINERID)查看一下容器的日志
    image

  • 可以看出数data目录没有权限,执行如下命令在启动试试
    chmod 777 /opt/minio/data:设置目录权限为可读可写可执行
    docker start 容器ID:启动容器
    image

(2)我们先在浏览器访问一下http://192.168.137.72:9000/

image

(3)我们在minio中创建一个bucket

(4)接下来我们创建一个SpringBoot项目

image

(5)导入相关的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.qbb</groupId>
    <artifactId>springboot-minio</artifactId>
    <version>1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.7.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>

        <!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>
        <!--swagger ui-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>

        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.3.0</version>
        </dependency>
    </dependencies>

</project>

(6)修改application.yml配置文件

server:
  port: 7200

spring:
  application:
    name: minio

app:
  minio:
    endpoint: http://192.168.137.72:9001
    accessKey: qbb
    secretKey: startqbb
    bucket: qbb

注意:9000是我们浏览器访问控制台的端口,而9001是SDK代码操作的端口

(7)主启动类

package com.qbb.minio;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
 * @version 1.0
 * @date 2022-05-20  15:45
 * @Description:
 */
@SpringBootApplication
public class MinioApplication {
    public static void main(String[] args) {
        SpringApplication.run(MinioApplication.class, args);
    }
}

(8)这里我配置一个swagger2方便测试,还配置了一个minio的配置类绑定配置文件信息,具体配置如下

package com.qbb.minio.config;

import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
 * @version 1.0
 * @date 2022-05-20  16:23
 * @Description:swagger配置类
 */
@Configuration
@EnableSwagger2
public class Swagger2Config {

    @Bean
    public Docket adminApiConfig() {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("minioApi")
                .apiInfo(adminApiInfo())
                .select()
                //只显示admin路径下的页面
                .paths(Predicates.and(PathSelectors.regex("/minio/.*")))
                .build();
    }

    private ApiInfo adminApiInfo() {

        return new ApiInfoBuilder()
                .title("minio-API文档")
                .version("1.0")
                .contact(new Contact("QIUQIU&LL", "https://www.cnblogs.com/qbbit", "startqbb@163.com"))
                .build();
    }
}



package com.qbb.minio.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
 * @version 1.0
 * @date 2022-05-20  18:57
 * @Description:
 */
@ConfigurationProperties(prefix = "app.minio")
@EnableConfigurationProperties
@Configuration
@Data
public class MinioConfig {

    private String endpoint;
    private String accessKey;
    private String secretKey;
    private String bucket;
}

(9)编写测试代码

package com.qbb.minio.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
 * @version 1.0
 * @date 2022-05-20  16:23
 * @Description:
 */
@Api(tags = "minio文件管理")
@RestController
@RequestMapping("/minio")
public class FileController {

    @ApiOperation("测试程序")
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

}

image

(10)接下来我们编写文件上传代码

package com.qbb.minio.controller;

import com.qbb.minio.config.MinioConfig;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.UUID;


/**
 * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
 * @version 1.0
 * @date 2022-05-20  16:23
 * @Description:
 */
@Api(tags = "minio文件管理")
@RestController
@RequestMapping("/minio")
public class FileController {

    @Autowired
    private MinioConfig minioConfig;

    @ApiOperation("测试程序")
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

    @ApiOperation("文件上传")
    @PostMapping("/fileUpload")
    public String fileUpload(MultipartFile file) {
        /**
         * 这里应该放在service层处理的,将上传的文件路径存入数据库,我就不这么麻烦了,直接返回给前端
         */
        String bucket = minioConfig.getBucket();
        String endpoint = minioConfig.getEndpoint();
        String accessKey = minioConfig.getAccessKey();
        String secretKey = minioConfig.getSecretKey();

        // 1.获取文件名
        String originalFilename = file.getOriginalFilename();

        // 2.修改文件名,防止上传重复文件名,导致文件覆盖
        String fileName = UUID.randomUUID().toString().replace("-", "") + "_" + originalFilename;
        // 文件流
        try (InputStream inputStream = file.getInputStream()) {
            // 3.使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
            MinioClient minioClient = new MinioClient(endpoint, accessKey, secretKey);

            // 4.检查存储桶是否已经存在
            boolean isExist = minioClient.bucketExists(bucket);
            if (isExist) {
                System.out.println("Bucket already exists");
            } else {
                // 不存在则创建一个名为bucket的存储桶,用于存储照片的zip文件。
                minioClient.makeBucket(bucket);
            }
            // 6.上传参数设置项
            PutObjectOptions options = new PutObjectOptions(inputStream.available(), -1);

            // 7.设置此次上传的文件的内容类型
            String contentType = file.getContentType();
            options.setContentType(contentType);

            // 8.上传
            minioClient.putObject(bucket, fileName, inputStream, options);

            // 9.访问路径
            String url = endpoint + "/" + bucket + "/" + fileName;
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}

(11)使用Swagger测试一下

image

(12)结果

  • swagger
    image

  • minio控制台
    image

(13)删除minio中的文件

 @ApiOperation("删除文件")
    @DeleteMapping("/remove")
    public boolean remove() {
        try {
            // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
            MinioClient minioClient = new MinioClient(minioConfig.getEndpoint(), minioConfig.getAccessKey(), minioConfig.getSecretKey());
            // 从bucket中删除文件(文件名)。
            minioClient.removeObject(minioConfig.getBucket(), "ed8aa56a8ec640d6a36a271ed4222605_xiaomi.png");
            System.out.println("successfully removed mybucket/myobject");
            return true;
        } catch (Exception e) {
            System.out.println("Error: " + e);
            return false;
        }
    }

(14)删除后的结果

  • swagger
    image

  • minio控制台
    image

(15)注意:我们配置完了,启动我们的项目可能会出现这么一个错误,说我们的请求时间与服务器时间相差太大

image

(16)解决办法,linux控制台

yum -y install ntp ntpdate:安装插件工具
hwclock --systohc:同步时间
docker restart minio镜像ID:重启镜像

至此SpringBoot整合Minio实现文件上传完成,更多详细的功能配置各位小伙伴可以参考minio官方

标签:存储,minio,springframework,String,import,org,搭建,com,MinIO
来源: https://www.cnblogs.com/qbbit/p/16291701.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有