Github 标星 32K+Star,16 分钟搭建高性能的文件服务器!

简介: Github 标星 32K+Star,16 分钟搭建高性能的文件服务器!
  • 1. MinIO 简介
  • 2. MinIO Server 安装
  • 3. MinIO Client 命令行工具
  • 4. Spring Boot 实战
  • 666. 彩蛋

本文在提供完整代码示例,可见 https://github.com/YunaiV/SpringBoot-Labs 的 lab-72-minio 目录。

原创不易,给点个 Star 嘿,一起冲鸭!

1. MinIO 简介

MinIO 是一个基于 Go 实现的高性能、兼容 S3 协议的对象存储。它采用 GNU AGPL v3 开源协议,项目地址是 https://github.com/minio/minio,官网是 https://min.io

它适合存储海量的非结构化的数据,例如说图片、音频、视频等常见文件,备份数据、容器、虚拟机镜像等等,小到 1 KB,大到 5 TB 都可以支持。

国内阿里巴巴、腾讯、百度、华为、中国移动、中国联通等企业在使用 MinIO,甚至不少商业公司二次开发 MinIO 来提供商业化的云存储产品。

疑问:为什么越来越少使用 FastDFS 实现文件存储服务呢?

部署运维复杂、无官方文档、缺乏长期维护的团队、性能较差、未提供 Docker & Kubernetes 集成方案等等原因。

本文,艿艿将带你使用 MinIO 来自建一个文件存储服务,并在 Spring Boot 项目中上传图片到 MinIO 中。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。

项目地址:https://github.com/YunaiV/ruoyi-vue-pro

2. MinIO Server 安装

由于 MinIO 是 Go 写的,所以就一个运行程序,因此安装部署 MinIO 就非常简单。

在文档 https://min.io/download 中,有 Windows、Linux、MacOS、Docker、Kubernetes、Source 六种安装方式。

下面,我们来安装下 MinIO,你可以选择适合你的方式。

2.1 快速安装

2.1.1 Windows

需要在 Windows PowerShell 中执行。

Invoke-WebRequest -Uri "https://dl.min.io/server/minio/release/windows-amd64/minio.exe" -OutFile "C:\minio.exe" ## 国外资源,龟速下载
setx MINIO_ROOT_USER admin
setx MINIO_ROOT_PASSWORD password
C:\minio.exe server F:\Data --console-address ":9001" ## F:\Data 存储目录;--console-address 是 UI 界面的端口

2.1.2 Linux

wget https://dl.min.io/server/minio/release/linux-amd64/minio ## 国外资源,龟速下载
chmod +x minio
MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password ./minio server /Users/yunai/minio --console-address ":9001" ## /Users/yunai/minio 存储目录;--console-address 是 UI 界面的端口

2.1.3 MacOS

wget https://dl.min.io/server/minio/release/darwin-amd64/minio ## 国外资源,龟速下载
chmod +x minio
MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password ./minio server F:\Data --console-address ":9001" ## F:\Data 存储目录;--console-address 是 UI 界面的端口

2.1.4 Docker

① Windows:

docker run -p 9000:9000 -p 9001:9001 -e "MINIO_ACCESS_KEY=admin" -e "MINIO_SECRET_KEY=password" minio/minio server /data --console-address ":9001" # /Users/yunai/minio 存储目录;--console-address 是 UI 界面的端口

② Linux 或 MacOS:

docker run -p 9000:9000 -p 9001:9001 -e "MINIO_ACCESS_KEY=admin" -e "MINIO_SECRET_KEY=password" minio/minio server /Users/yunai/minio --console-address ":9001" ## /Users/yunai/minio 存储目录;--console-address 是 UI 界面的端口

2.2 访问 UI 界面

使用浏览器访问 http://127.0.0.1:9001 地址,访问 MinIO 内置的 UI 界面。

输入账号 admin,密码 password 进行登录,成功进入首页。

1.png

2.3 新建存储桶

点击 [Create Bucket] 按钮,新建一个 Bucket 存储桶,用于稍后文件的上传。

2.png

2.4 添加 readonly 访问规则

默认配置下,访问存储桶是需要请求授权的。但是在实际场景下,我们往往希望允许直接访问,此时就需要添加一条 readonly 访问规则。

① 点击右上角的 [Configure Bucket] 设置图标,然后选择 [Access Rules] 菜单。

3.png

② 点击 [Add Access Rule] 按钮,添加一条 Prefix 为 / Access 为 readonly 的规则。

4.png

2.5 上传文件

点击 [Upload] 按钮,点击 [Upload File] 选项,选择一个图片上传。

5.png

2.6 访问文件

文件的访问地址的格式为 <http://127.0.0.1:9000/{bucket}/{name}>,注意是 9000 端口。

我们刚上传的文件 {bucket} 是 yudaoyuanma,{name} 是 822aebded6e6414e912534c6091771a4.jpg,所以最终的访问路径是 http://127.0.0.1:9000/yudaoyuanma/822aebded6e6414e912534c6091771a4.jpg。

基于微服务的思想,构建在 B2C 电商场景下的项目实战。核心技术栈,是 Spring Boot + Dubbo 。未来,会重构成 Spring Cloud Alibaba 。

项目地址:https://github.com/YunaiV/onemall

3. MinIO Client 命令行工具

MinIO Client (mc) 是 MinIO 提供的命令行工具,用于访问 MinIO Server。它的命令设计的非常棒,和我们在使用 ls、cat、cp、mirror、diff、find 等 Unix 命令基本接近,主要如下:

ls       列出文件和文件夹
mb       创建一个存储桶或一个文件夹
cat      显示文件和对象内容
pipe     将一个 STDIN 重定向到一个对象或者文件或者 STDOUT
share    生成用于共享的 URL
cp       拷贝文件和对象
mirror   给存储桶和文件夹做镜像
find     基于参数查找文件
diff     对两个文件夹或者存储桶比较差异
rm       删除文件和对象
events   管理对象通知
watch    监听文件和对象的事件
policy   管理访问策略
session  为 cp 命令管理保存的会话
config   管理 mc 配置文件
update   检查软件更新
version  输出版本信息

例如说,使用 mc ls 列出有哪些 Bucket 存储桶:

6.png

考虑到你对 MinIO Client 可能不是很感兴趣,艿艿就暂时不过多啰嗦。感兴趣的话,可以看看如下文档:

4. Spring Boot 实战

示例代码对应仓库:lab-72-minio 。

接下来,我们来新建一个 Spring Boot 项目 lab-72-minio ,实现文件的上传与删除的功能。

4.1 引入依赖

pom.xml 文件中,引入 MinIO 相关依赖。

<?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">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>lab-72-minio</artifactId>
    <dependencies>
        <!-- 实现对 Spring MVC 的自动化配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- MinIO 客户端 -->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.2.2</version>
        </dependency>
    </dependencies>
</project>

注意,如果引入的 Minio 的版本过高,例如说 8.3.7,会报依赖的冲突:

2022-03-19 11:29:59.954 ERROR 77692 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
    io.minio.S3Base.<clinit>(S3Base.java:98)
The following method did not exist:
    okhttp3.RequestBody.create([BLokhttp3/MediaType;)Lokhttp3/RequestBody;
The calling method's class, io.minio.S3Base, was loaded from the following location:
    jar:file:/Users/yunai/.m2/repository/io/minio/minio/8.3.7/minio-8.3.7.jar!/io/minio/S3Base.class
The called method's class, okhttp3.RequestBody, is available from the following locations:
    jar:file:/Users/yunai/.m2/repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar!/okhttp3/RequestBody.class
The called method's class hierarchy was loaded from the following locations:
    okhttp3.RequestBody: file:/Users/yunai/.m2/repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar
Action:
Correct the classpath of your application so that it contains compatible versions of the classes io.minio.S3Base and okhttp3.RequestBody

4.2 MinIOConfiguration

新建 MinIOConfiguration 配置类,创建 MinioClient Bean。代码如下:

package cn.iocoder.springboot.lab72.config;
import io.minio.MinioClient;
import org.springframework.context.annotation.*;
@Configuration
public class MinIOConfiguration {
    @Bean
    public MinioClient minioClient() {
        // Minio 配置。实际项目中,定义到 application.yml 配置文件中
        String endpoint = "http://127.0.0.1:9000";
        String accessKey = "admin";
        String secretKey = "password";
        // 创建 MinioClient 客户端
        return MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKey, secretKey)
                .build();
    }
}

4.3 FileController

新建 FileController 类,实现文件上传与删除的 RESTful API 接口。代码如下:

package cn.iocoder.springboot.lab72.controller;
import io.minio.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.UUID;
@RestController
@RequestMapping("/file")
public class FileController {
    @Resource
    private MinioClient minioClient;
    // Minio 配置。实际项目中,定义到 application.yml 配置文件中
    private String endpoint = "http://127.0.0.1:9000";
    private String bucket = "yudaoyuanma";
    /**
     * 上传文件
     */
    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) throws Exception {
        // 上传
        String path = UUID.randomUUID().toString(); // 文件名,使用 UUID 随机
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(bucket) // 存储桶
                .object(path) // 文件名
                .stream(file.getInputStream(), file.getSize(), -1) // 文件内容
                .contentType(file.getContentType()) // 文件类型
                .build());
        // 拼接路径
        return String.format("%s/%s/%s", endpoint, bucket, path);
    }
    /**
     * 删除文件
     */
    @DeleteMapping("/delete")
    public void delete(@RequestParam("path") String path) throws Exception {
        minioClient.removeObject(RemoveObjectArgs.builder()
                .bucket(bucket) // 存储桶
                .object(path) // 文件名
                .build());
    }
}

4.4 MinIOApplication

新建 MinIOApplication 启动类。代码如下:

package cn.iocoder.springboot.lab72;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MinIOApplication {
    public static void main(String[] args) {
        SpringApplication.run(MinIOApplication.class, args);
    }
}

4.5 简单测试

① 执行 MinIOApplication 启动 Spring Boot 项目。

② 使用 Postman 调用 /file/upload 接口,进行文件的上传。

7.png

上传成功后,我们获得了文件的访问 URL 地址,可以使用浏览器直接访问。

同时在 MinIO 后台界面,也可以查询到该文件。

9.png

③ 使用 Postman 调用 /file/delete 接口,进行文件的删除。

10.png

666. 彩蛋

未来是过去历史的一再重演,技术圈也是一样。

  • 2009 年,Oracle 公司收购 Sun,将 MySQL 收入囊中;同年,MySQL 之父 Widenius 离开 Sun,发布 MariaDB 产品。
  • 2011 年,RedHat 公司收购 Gluster,将 GlusterFS 纳入麾下;2014 年,Gluster 创始人发布 Minio 产品。

最后,推荐下艿艿在 https://github.com/YunaiV/ruoyi-vue-pro 实现的文件模块,支持 S3(MinIO、阿里云、腾讯云、华为云、七牛云等等)、磁盘、数据库等多种存储器。感兴趣的话,可以看看 https://doc.iocoder.cn/file 文档。

相关文章
|
4月前
|
Rust Linux iOS开发
|
1月前
|
算法 数据处理 数据安全/隐私保护
|
27天前
|
Rust 安全 开发者
惊爆!Xamarin 携手机器学习,开启智能应用新纪元,个性化体验与跨平台优势完美融合大揭秘!
【8月更文挑战第31天】随着互联网的发展,Web应用对性能和安全性要求不断提高。Rust凭借卓越的性能、内存安全及丰富生态,成为构建高性能Web服务器的理想选择。本文通过一个简单示例,展示如何使用Rust和Actix-web框架搭建基本Web服务器,从创建项目到运行服务器全程指导,帮助读者领略Rust在Web后端开发中的强大能力。通过实践,读者可以体验到Rust在性能和安全性方面的优势,以及其在Web开发领域的巨大潜力。
30 0
|
1月前
|
缓存 监控 Linux
在Linux中,如何设计一个高性能的Web服务器?
在Linux中,如何设计一个高性能的Web服务器?
|
2月前
|
机器人 vr&ar 计算机视觉
|
3月前
|
Shell Python
GitHub星标破千Star!Python游戏编程的初学者指南
Python 是一种高级程序设计语言,因其简洁、易读及可扩展性日渐成为程序设计领域备受推崇的语言。 目前的编程书籍大多分为两种类型。第一种,与其说是教编程的书,倒不如说是在教“游戏制作软件”,或教授使用一种呆板的语言,使得编程“简单”到不再是编程。而第二种,它们就像是教数学课一样教编程:所有的原理和概念都以小的应用程序的方式呈现给读者。
|
2月前
|
监控 JavaScript 前端开发
JavaScript与Nest.js:打造高性能的服务器端应用
Nest.js是Node.js的渐进式框架,融合OOP、FP和FRP,提供模块化、装饰器和依赖注入,助建高性能服务器应用。选择Nest.js的原因包括模块化设计、简洁的装饰器API和高性能基础(如Express或Fastify)。开始使用需安装Node.js和`@nestjs/cli`,创建项目、编写控制器。深入学习涉及模块化、服务的依赖注入及中间件。安全性优化涵盖HTTPS、CORS策略、限流和性能监控。
69 0
|
3月前
|
JavaScript Serverless 网络架构
Next.js与SSR:构建高性能服务器渲染应用
创建Next.js项目使用`create-next-app`,每个页面自动支持SSR。动态路由如`pages/posts/[id]`,在`getStaticPaths`和`getServerSideProps`中获取数据。利用静态优化和预渲染提升性能,动态导入减少初始加载时间。使用`next/image`优化图片,自定义服务器增加控制,集成第三方库如Redux。优化SEO,利用i18n支持多语言,使用Serverless模式和Web Workers。项目支持TypeScript,创建`_error.js`处理错误,部署到Vercel并使用工具进行性能监控和优化。
196 4
|
3月前
|
前端开发 Java C#
GitHub突破5k Star!这件事情我坚持了3年,努力打造C#/.NET/.NET Core全面的学习、工作、面试指南知识库
GitHub突破5k Star!这件事情我坚持了3年,努力打造C#/.NET/.NET Core全面的学习、工作、面试指南知识库
|
3月前
|
Python 容器
GitHub狂揽6700 Star,Python进阶必备的案例、技巧与工程实践
当下是 Python 急剧发展的时代,越来越多的人开始学习和使用Pyhon,而大家也遇到了各种问题。这份手册清晰、细致地介绍了 Python 代码应该遵循的编程风格,并解释了背后的原理和机制。