当前位置: 首页 > news >正文

SpringBoot与Minio的极速之旅:解锁文件切片上传新境界

目录

一、前言

二、对象存储(Object Storage)介绍

(1)对象存储的特点

(2)Minio 与对象存储

(3)对象存储其他存储方式的区别

(4)对象存储的应用场景

三、Minio基础介绍

(1)主要特性

(2)应用场景

(3)架构和部署

四、SringBoot集成MinIO实现切片上传

1. 引入依赖

2.配置MinIO相关配置信息

3. 配置 MinIO 客户端

4. 创建文件切片上传服务

5. 创建文件切片上传控制器

6.测试及说明


一、前言

在数字化时代,文件上传是众多应用不可或缺的一环。随着文件体积的增大和用户对上传速度的追求,传统的上传方式已难以满足需求。SpringBoot作为Java开发者的利器,结合Minio这一高性能对象存储解决方案,为我们提供了一种全新的文件上传体验——文件切片极速上传。

本文将带领读者深入探索SpringBoot与Minio的结合,通过文件切片技术,实现高效、稳定的文件上传。我们将从基础概念出发,逐步介绍这个文件切片上传系统,解锁上传速度的新境界。希望对正在研究文件存储的小伙伴们有所启发~

二、对象存储(Object Storage)介绍

首先简单介绍一下对象存储的相关概念~~~

对象存储是一种数据存储架构,它将数据作为对象进行管理,而不是传统的文件系统或块存储方式。每个对象通常包含数据本身、元数据和唯一标识符。对象存储适用于大规模数据存储和高并发访问场景,具有高扩展性、高可靠性和低成本的特点。

(1)对象存储的特点

  1. 高扩展性

    • 对象存储系统可以轻松扩展存储容量,通过增加存储节点来满足不断增长的数据需求。

  2. 高可靠性

    • 对象存储系统通常采用数据冗余和分布式存储技术,确保数据的高可用性和可靠性。即使部分节点故障,数据也不会丢失。

  3. 低成本

    • 对象存储采用廉价的存储介质(如硬盘),并通过数据压缩和去重技术减少存储空间的占用,从而降低存储成本。

  4. 丰富的元数据

    • 每个对象都包含丰富的元数据,可以用于描述数据的属性、访问权限等信息,方便数据的检索和管理。

  5. RESTful API

    • 对象存储系统通常提供 RESTful API,方便开发者通过 HTTP 协议进行数据的上传、下载和管理。

(2)Minio 与对象存储

Minio 是一个典型的对象存储解决方案,它完全兼容 Amazon S3 API,提供了以下对象存储的核心功能:

  1. 对象管理

    • Minio 将数据作为对象进行管理,每个对象包含数据本身、元数据和唯一标识符。用户可以通过 S3 API 进行对象的创建、读取、更新和删除操作。

  2. 存储桶(Bucket)

    • 存储桶是对象的容器,类似于文件系统中的目录。用户可以在 Minio 中创建和管理多个存储桶,每个存储桶可以包含多个对象。

  3. 访问控制

    • Minio 支持基于存储桶和对象的访问控制,用户可以通过策略(Policy)和访问控制列表(ACL)来管理数据的访问权限。

  4. 数据冗余

    • Minio 支持分布式部署,通过数据冗余技术确保数据的高可用性和可靠性。分布式 Minio 可以自动处理数据复制和故障恢复。

  5. 数据加密

    • Minio 支持数据加密,包括服务器端加密和客户端加密,确保数据在传输和存储过程中的安全性。

  6. RESTful API

    • Minio 提供 RESTful API,方便开发者通过 HTTP 协议进行数据的管理和访问。

(3)对象存储其他存储方式的区别

对象存储(Object Storage)和普通存储(包括文件存储和块存储)是三种不同的数据存储架构,它们在数据管理方式、扩展性、性能和应用场景等方面存在显著差异。

存储方式数据管理方式扩展性性能应用场景优点缺点
对象存储数据作为对象进行管理,每个对象包含数据本身、元数据和唯一标识符。对象存储通常提供 RESTful API 进行数据访问和管理。具有极高的扩展性,可以通过增加存储节点来扩展存储容量和提高性能。适用于大规模数据访问和高并发场景,具有较高的吞吐量和较低的延迟。适用于大规模数据存储和高并发访问场景,如静态网站托管、大数据处理、备份和归档、云原生应用等。

高扩展性:可以轻松扩展存储容量和性能;

高可靠性:通过数据冗余和分布式存储确保数据的高可用性和可靠性;

低成本:采用廉价的存储介质,并通过数据压缩和去重技术降低存储成本;

丰富的元数据:每个对象包含丰富的元数据,方便数据的检索和管理;

RESTful API:提供 RESTful API,方便开发者进行数据访问和管理。

延迟较高:相对于块存储,对象存储的延迟较高,不适用于对延迟要求极高的应用场景。

复杂性:对象存储的架构和管理相对复杂,需要专业的技术团队进行维护。

文件存储数据作为文件和目录层次结构进行管理,类似于传统的文件系统。文件存储通常提供文件路径进行数据访问。扩展性有限,通常受限于单个服务器的存储容量和性能。适用于中小规模数据访问,性能受限于单个服务器的处理能力。适用于文件共享和协作场景,如企业文件服务器、网络附加存储(NAS)等。

简单易用:文件存储的架构和管理相对简单,易于使用和维护。

兼容性:兼容传统的文件系统操作,方便用户进行数据访问和管理。

扩展性有限:受限于单个服务器的存储容量和性能,难以扩展。

性能有限:性能受限于单个服务器的处理能力,不适用于高并发和大规模数据访问场景。

块存储数据作为固定大小的块进行管理,每个块具有唯一的标识符。块存储通常作为虚拟机的存储卷使用,提供低延迟的数据访问。扩展性一般,通常通过增加存储设备或扩展存储区域网络(SAN)来提高存储容量。提供低延迟的数据访问,适用于对性能要求较高的应用场景,如数据库和虚拟机。适用于对性能要求较高的应用场景,如数据库、虚拟化环境、高性能计算等。

低延迟:提供低延迟的数据访问,适用于对性能要求较高的应用场景。

高性能:适用于数据库、虚拟化环境等高性能计算场景。

扩展性有限:通常通过增加存储设备或扩展存储区域网络(SAN)来提高存储容量,扩展性有限。

成本较高:相对于对象存储,块存储的成本较高,特别是在大规模存储场景下。

(4)对象存储的应用场景

对象存储适用于多种应用场景,包括但不限于:

  • 静态网站托管:对象存储可以作为静态网站的存储和分发平台,提供高速的内容传输。

  • 大数据处理:对象存储可以作为大数据处理框架(如 Hadoop、Spark)的存储后端,提供高效的数据访问。

  • 备份和归档:对象存储可以用于企业数据的备份和归档,确保数据的安全性和可恢复性。

  • 云原生应用:对象存储与 Kubernetes 等容器编排平台无缝集成,适用于云原生应用的存储需求。

三、Minio基础介绍

Minio 是一个开源的高性能对象存储解决方案,专为云原生应用设计。它兼容 Amazon S3 API,提供了简单、可靠的存储服务,适用于各种规模的应用场景。Minio 的设计理念是轻量级和高性能,使其成为容器化和微服务架构中的理想选择。

(1)主要特性

  1. 兼容 S3 API

    • Minio 完全兼容 Amazon S3 API,这意味着开发者可以使用现有的 S3 客户端和工具与 Minio 进行交互,无需修改代码。

  2. 分布式存储

    • Minio 支持分布式部署,可以通过扩展节点来增加存储容量和提高性能。分布式 Minio 可以自动处理数据冗余和故障恢复,确保数据的高可用性和可靠性。

  3. 高性能

    • Minio 采用 Go 语言编写,具有出色的性能和低延迟。它能够处理大规模的数据传输,适用于高并发场景。

  4. 数据安全

    • Minio 支持数据加密(包括服务器端加密和客户端加密),确保数据在传输和存储过程中的安全性。

  5. 简单易用

    • Minio 的安装和配置非常简单,支持多种操作系统和平台。它还提供了丰富的管理工具和 API,方便开发者进行管理和监控。

  6. 开源免费

    • Minio 是开源项目,采用 Apache License 2.0 许可,用户可以免费使用并对其进行二次开发。

(2)应用场景

Minio 适用于多种应用场景,包括但不限于:

  • 静态网站托管:Minio 可以作为静态网站的存储和分发平台,提供高速的内容传输。

  • 大数据处理:Minio 可以作为大数据处理框架(如 Hadoop、Spark)的存储后端,提供高效的数据访问。

  • 备份和归档:Minio 可以用于企业数据的备份和归档,确保数据的安全性和可恢复性。

  • 云原生应用:Minio 与 Kubernetes 等容器编排平台无缝集成,适用于云原生应用的存储需求。

(3)架构和部署

Minio 支持单节点和分布式部署两种模式:

  • 单节点部署:适用于小规模应用和开发测试环境。单节点 Minio 部署简单,易于管理。

  • 分布式部署:适用于大规模应用和高可用性需求。分布式 Minio 通过多个节点组成存储集群,提供更高的性能和可靠性。

Minio 的部署可以通过 Docker 容器、Kubernetes 集群或直接在物理服务器上进行。它还提供了丰富的命令行工具和 Web 管理界面,方便用户进行配置和管理。这里主要介绍SpringBoot与minio的集成,因此这块笔者就不单独说明部署的详细方式了,仅采用容器化单实例服务进行。

#自定义账号密码运行容器
[root@node01 ~]# docker run -d \
> -p 9000:9000 \
> -p 9001:9001 \
> --name minio \
> -v /data/minio/data:/data \
> -e "MINIO_ROOT_USER=admin" \
> -e "MINIO_ROOT_PASSWORD=admin123" \
> swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/minio/minio:RELEASE.2024-06-13T22-53-53Z server /data --console-address ":9001"
Unable to find image 'swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/minio/minio:RELEASE.2024-06-13T22-53-53Z' locally
RELEASE.2024-06-13T22-53-53Z: Pulling from ddn-k8s/docker.io/minio/minio
d95a8f5a9b46: Pull complete 
392be19a63f6: Pull complete 
86f90f8ca150: Pull complete 
7dc3c1e5f08a: Pull complete 
1ab6ab2ba6f0: Pull complete 
6fac698163eb: Pull complete 
6a4e2f681031: Pull complete 
53a5b322abdc: Pull complete 
Digest: sha256:98fe67c08bf95945b34f8e74622976495e6c47b3e8dd2faed079ac2804b98c97
Status: Downloaded newer image for swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/minio/minio:RELEASE.2024-06-13T22-53-53Z

四、SringBoot集成MinIO实现切片上传

1. 引入依赖

首先,在你的 pom.xml 文件中引入必要的依赖,包括 minio 和其他相关依赖:

<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.7</version>
</dependency>
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.5</version>
</dependency>
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version>
</dependency>

2.配置MinIO相关配置信息

首先需要在MinIO服务页面配置一个令牌桶(Bucket),MinIO使用bucket来组织对象。bucket类似于文件系统中的文件夹或目录,其中每个bucket可以容纳任意数量的对象。这里咱们创建一个名为test的bucket。

  • versioning(版本控制):允许在同一键下保持同一对象的多个版本。

  • Object Locking(对象锁定):防止对象被删除。需要支持保留和合法持有。只能在创建桶时启用。

  • Quota(配额):限制bucket中的数据量。

  • Retention(存放):开启会施加规则,在一段时间内防止对象删除。为了设置桶保留策略,必须启用版本控制。

然后需要创建API的访问凭证,这个用于minio在springboot配置文件中使用时的配置。

完成后保留好access key和secret key信息。接下来可以在springboot的yml配置文件中配置minio的相关信息了:

server:port: 8919
spring:servlet:multipart:enabled: truemax-file-size: 2048MBmax-request-size: 2048MBconfig:file-server:#文件服务,local/minio,local本地文件服务,minio minio服务type: miniolocal:secret: e9eaa184ac1b4068829edb4f3ea978f4# 防盗链st有效时长(秒)st-effective-time: 300file-dir: D:/springboot-test/uploadFilepreview-url: http://127.0.0.1:8918minio:access-key: ZTsent9wl6UlKBGiNoaDsecret-key: b1CXhMIovbevJ2q9LQuPR4lhaFNCqSlX2o5EgQtWurl: http://192.168.1.201:9000bucket-name: test
  • access-keysecret-key是访问minio服务的凭证,就是上面刚创建的。

  • url是minio服务的地址,这里要区分web端的访问地址9001,默认9000是mino的服务地址。

  • bucket-name是存储文件的桶名,这个咱们生成的名称是test。

3. 配置 MinIO 客户端

在你的 SpringBoot 应用中配置 MinIO 客户端。可以通过创建一个配置类来实现:

package com.yy.fs.config;
​
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
/*** Minio 配置** @author young* @date 2024/09/03*/
@Configuration
@Data
@ConfigurationProperties("config.file-server.minio")
public class MinioConfig {private String accessKey;private String secretKey;private String url;private String bucketName;
​@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();}
}

4. 创建文件切片上传服务

创建一个服务类来处理文件切片上传的逻辑:

package com.yy.fs.mytest;
​
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
​
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;
​
@Service
public class FileUploadService {
​private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadService.class);@Autowiredprivate MinioClient minioClient;
​/** uploadChunk 用于上传文件块,参数包括桶名、对象名和文件块。*/public void uploadChunk(String bucketName, String objectName,  MultipartFile chunkFile) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {// 检查指定的桶是否存在,如果不存在则创建一个新的桶。boolean isExist =minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());if (!isExist) {// Make a new bucket called bucket.minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());} else {LOGGER.info("Bucket " + bucketName + " already exists.");}byte[] bytes = chunkFile.getBytes();ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
​String suffix = objectName.contains(".") ? objectName.substring(objectName.lastIndexOf(".")):"";// 使用MinIO客户端上传文件块到指定的桶和对象名minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName.substring(0,objectName.lastIndexOf(".")) + "_chunk"  + suffix).stream(byteArrayInputStream, byteArrayInputStream.available(), -1).build());}
}

5. 创建文件切片上传控制器

创建一个控制器来处理文件切片上传的请求,在实际项目中根据前端的参数传入即可:

package com.yy.fs.mytest;
​
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
​
@RestController
public class FileUploadController {
​@Autowiredprivate FileUploadService fileUploadService;
​@PostMapping("/uploadChunk")public String uploadChunk(@RequestParam("bucketName") String bucketName,@RequestParam("objectName") String objectName,@RequestParam("chunkFile") MultipartFile chunkFile) {try {fileUploadService.uploadChunk(bucketName, objectName,  chunkFile);return "Chunk  uploaded successfully";} catch (Exception e) {e.printStackTrace();return "Failed to upload chunk ";}}
}

6.测试及说明

最后使用测试工具测试一下,这里咱们上传一个视频文件进行测试:

上传成功后可以在MinIO界面查看到已上传的视频信息:

并且支持下载,预览与分享,基本算一个文件存储系统类似的玩意。但是实际在服务存储的目录下就不同了:

data目录下随着我们创建一个test的桶而生成了一个test文件,当文件通过后端接口传入minio后根据文件大小自动被切片为了很多小文件,这也难怪他的文件上传速度要比直接上传整个文件高效多了。更主要的是可以省略去构建切片方法实现切片逻辑的步骤,让minio自己完成。感兴趣的小伙伴可参考下方链接继续研究一下~

参考地址:MinIO中文文档

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • pytorch torch.matmul函数介绍
  • 基于SpringBoot的宠物服务系统+uniapp小程序+LW参考示例
  • 【redis】redis的特性和主要应用场景
  • 码上君量化互助社群介绍
  • javascript嵌套循环
  • 使用shell脚本安装mysql8,进行主从备份配置
  • route-forward springboot实现路由转发程序
  • 系统架构师-ERP+集成
  • lwip移植-基于类rtosw5500
  • 实例:如何统计当前主机的连接状态和连接数
  • 实习项目|苍穹外卖|day8
  • 【机器学习】和【人工智能】在物理学领域的应用以及代码案例分析
  • SpringMVC使用:类型转换数据格式化数据验证
  • Linux 路径写法,目录相关命令及文件管理命令
  • 软件工程知识点总结(1):软件工程概述
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • centos安装java运行环境jdk+tomcat
  • Docker容器管理
  • flask接收请求并推入栈
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • Java精华积累:初学者都应该搞懂的问题
  • JS实现简单的MVC模式开发小游戏
  • Logstash 参考指南(目录)
  • Python爬虫--- 1.3 BS4库的解析器
  • Python学习之路13-记分
  • 回顾 Swift 多平台移植进度 #2
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 温故知新之javascript面向对象
  • 再次简单明了总结flex布局,一看就懂...
  • gunicorn工作原理
  • ​secrets --- 生成管理密码的安全随机数​
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (附源码)计算机毕业设计高校学生选课系统
  • (六)软件测试分工
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • .NET MVC、 WebAPI、 WebService【ws】、NVVM、WCF、Remoting
  • .NET 命令行参数包含应用程序路径吗?
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • /usr/bin/env: node: No such file or directory
  • [ C++ ] STL---仿函数与priority_queue
  • [ web基础篇 ] Burp Suite 爆破 Basic 认证密码
  • [ 转载 ] SharePoint 资料
  • [1159]adb判断手机屏幕状态并点亮屏幕