springboot整合minio做文件存储

一,minio介绍

MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。

MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。

官方文档:MinIO对象存储 Kubernetes --- MinIO中文文档 | MinIO Kubernetes中文文档 旧一点

MinIO Object Storage for Kubernetes --- MinIO Object Storage for Kubernetes

应用场景

单主机单硬盘模式

单主机多硬盘模式

多主机多硬盘分布式

特点

· 高性能:作为高性能对象存储,在标准硬件条件下它能达到55GB/s的读、35GB/s的写速率

· 可扩容:不同MinIO集群可以组成联邦,并形成一个全局的命名空间,并跨越多个数据中心

· 云原生:容器化、基于K8S的编排、多租户支持

· Amazon S3兼容:Minio使用Amazon S3 v2 / v4 API。可以使用Minio SDK,Minio Client,AWS SDK和AWS CLI访问Minio服务器。

· 可对接后端存储: 除了Minio自己的文件系统,还支持DAS、 JBODs、NAS、Google云存储和Azure Blob存储。

· SDK支持: 基于Minio轻量的特点,它得到类似Java、Python或Go等语言的sdk支持

· Lambda计算: Minio服务器通过其兼容AWS SNS / SQS的事件通知服务触发Lambda功能。支持的目标是消息队列,如Kafka,NATS,AMQP,MQTT,Webhooks以及Elasticsearch,Redis,Postgres和MySQL等数据库。

· 有操作页面

· 功能简单: 这一设计原则让MinIO不容易出错、更快启动

· 支持纠删码:MinIO使用纠删码、Checksum来防止硬件错误和静默数据污染。在最高冗余度配置下,即使丢失1/2的磁盘也能恢复数据**!**

存储机制

Minio使用纠删码erasure code和校验和checksum。 即便丢失一半数量(N/2)的硬盘,仍然可以恢复数据。

纠删码是一种恢复丢失和损坏数据的数学算法**。**

二,搭建安装

docker pull minio/minio
新版本: 
docker run \
  -p 9000:9000 \
  -p 9001:9001 \
  --name minio \
  -d --restart=always \
  -e "MINIO_ROOT_USER=admin" \
  -e "MINIO_ROOT_PASSWORD=admin123456" \
  -v /home/data:/data \
  -v /home/config:/root/.minio \
  minio/minio server /data --console-address ":9001"

浏览器访问:http://IP:9000/minio/login,如图:

三,使用

3.1引入依赖

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.2.0</version>
</dependency>

3.2创建文件上传的controller FileController

注意:一些参数不能写死,需要写到配置文件里面进行动态读取

minio:
  endpointUrl: http://192.168.17.166:9000
  accessKey: admin
  secreKey: admin123456
  bucketName: gmall
java 复制代码
@RestController
@RequestMapping("/admin/product")
public class FileController {
    //由于参数不固定,因此需要从配置文件读取,有两种方式①@value注解②创建实体类使用@configurationproperties注解指定前缀注入
    @Value("${minio.endpointUrl}")
    private String endpointUrl; //文件服务器登录地址
    @Value("${minio.accessKey}")
    private String accessKey; //用户名
    @Value("${minio.secreKey}")
    private String secreKey;  //密码
    @Value("${minio.bucketName}")
    private String bucketName; //储存桶名称


    /**
     * @Description: 上传图片到minio文件服务器
     * @Param: MultipartFile
     * @return:
     * @Author: Mr.Zhan
     * @Date: 2022/3/28  17:59
     */
    @PostMapping("/fileUpload")
    public Result fileUpload(MultipartFile file) {
        String result =null;
        try {
            // 创建minio的客户端
            MinioClient minioClient =
                    MinioClient.builder()
                            .endpoint(endpointUrl)  //指定文件服务器地址,用户名,密码
                            .credentials(accessKey, secreKey)
                            .build();

            // 判断存储桶是否存在
            boolean found =
                    minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!found) {
                // 不存在则创建一个桶
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            } else {
                throw new GmallException("存储桶已经存在", 20001);
            }

            //准备上传的图片名称
            String fileName = System.currentTimeMillis() + UUID.randomUUID().toString().replaceAll("-", "") + file.getOriginalFilename();
            //使用流上传文件
            /*
             * ①bucketName 存储桶名字
             * ②fileName   文件名称
             * ③ file.getInputStream() 文件流
             * ④file.getSize()文件大小
             * file.getContentType() 文件类型
             * */
            minioClient.putObject(
                    PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(
                            file.getInputStream(), file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build());
            result=endpointUrl + "/" + bucketName + "/" + fileName;

            
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        }
        return Result.ok(result);
    }
}

3.3登陆控制台设置桶的状态为公开

四,注意

注意:文件上传时,需要调整一下linux 服务器的时间与windows 时间一致!
第一步:安装ntp服务
yum -y install ntp

第二步:开启开机启动服务
systemctl enable ntpd

第三步:启动服务
systemctl start ntpd

第四步:更改时区
timedatectl set-timezone Asia/Shanghai

第五步:启用ntp同步
timedatectl set-ntp yes

第六步:同步时间
ntpq -p
相关推荐
ABin-阿斌几秒前
SpringBoot 整合 Easy_Trans 实现翻译的具体介绍
java·spring boot·后端
菜鸟求带飞_2 分钟前
算法打卡:第十一章 图论part03
java·数据结构·算法·深度优先·图论
圆头圆脑圆JAVA3 分钟前
简单了解微服务--黑马(在更)
java·spring boot·微服务
木子欢儿10 分钟前
在 Debian 12 上安装 Java 21
java·运维·开发语言·debian
一二小选手13 分钟前
【高级编程】XML DOM4J解析XML文件(含案例)
xml·java
终末圆14 分钟前
MyBatis XML映射文件编写【后端 18】
xml·java·开发语言·后端·算法·spring·mybatis
就这个java爽!15 分钟前
超详细的XML介绍【附带dom4j操作XML】
xml·java·开发语言·数据库·青少年编程·eclipse
kunkun10117 分钟前
Mybatis的XML实现方法
xml·java·mybatis
libai23 分钟前
STM32 USB HOST CDC 驱动CH340
java·前端·stm32
IT学长编程24 分钟前
计算机毕业设计 数字化农家乐管理平台的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·毕业论文·计算机毕业设计选题·计算机毕业设计开题报告·农家乐管理平台