MinIO 入门实战:Docker 安装 + Spring Boot 文件上传(公有 / 私有)

文章目录

  • [一、MinIO 简介](#一、MinIO 简介)
  • [二、MinIO 的核心特点](#二、MinIO 的核心特点)
  • [三、Docker 安装 MinIO](#三、Docker 安装 MinIO)
  • 四、时间同步问题
  • [五、Spring Boot 文件上传到 MinIO](#五、Spring Boot 文件上传到 MinIO)
  • 六、总结

一、MinIO 简介

MinIO 是一个基于 Apache License v3.0 的开源对象存储服务,兼容 Amazon S3 API ,非常适合存储大规模 非结构化数据,例如:

  • 图片
  • 视频
  • 日志文件
  • 备份数据
  • 容器 / 虚拟机镜像

单个对象大小可从 KB 级别到最大 5TB

与传统的存储服务相比,MinIO 非常 轻量级 ,可以像 Redis、MySQL、Node.js 一样轻松集成到各种系统中。

👉 官方文档(英文):
https://docs.min.io/


二、MinIO 的核心特点

1. 高性能

在标准硬件环境下,MinIO 可达到:

  • 55 GB/s 读取速度
  • 35 GB/s 写入速度

非常适合高并发、大文件读写场景。

2. 高可扩展

  • 支持多个 MinIO 集群组成 联邦
  • 形成 全局命名空间
  • 支持跨数据中心部署

3. 云原生

  • 支持容器化部署
  • 可运行在 Kubernetes
  • 支持多租户

4. 完全兼容 Amazon S3

  • 支持 S3 v2 / v4 API

  • 可直接使用:

    • MinIO SDK
    • AWS SDK
    • AWS CLI

5. 多种后端存储

  • 本地文件系统
  • DAS / JBOD
  • NAS
  • Google Cloud Storage
  • Azure Blob Storage

6. SDK 与生态完善

支持多种语言 SDK:

  • Java
  • Python
  • Go 等

7. 事件与 Lambda 计算

支持通过 事件通知 触发 Lambda,兼容 AWS SNS / SQS,可对接:

  • Kafka
  • Redis
  • MySQL
  • Elasticsearch
  • WebHook 等

8. 纠删码机制(Erasure Code)

MinIO 使用 纠删码 + 校验和

即使丢失 一半磁盘(N/2),仍然可以恢复数据

这是基于数学算法的数据容错机制,极大提高了数据安全性。


三、Docker 安装 MinIO

1. 拉取镜像

bash 复制代码
docker pull minio/minio

2. 启动容器

bash 复制代码
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"

3. 访问控制台

浏览器访问:

复制代码
http://IP:9001/minio/login

登录账号:

  • 用户名:admin
  • 密码:admin123456

四、时间同步问题

在上传文件时,如果 Linux 服务器时间与 Windows 时间不一致,可能会导致 MinIO 访问异常。

使用 NTP 同步时间

bash 复制代码
# 1. 安装 ntp
yum -y install ntp

# 2. 设置开机启动
systemctl enable ntpd

# 3. 启动服务
systemctl start ntpd

# 4. 设置时区
timedatectl set-timezone Asia/Shanghai

# 5. 启用 NTP
timedatectl set-ntp yes

# 6. 查看同步状态
ntpq -p

五、Spring Boot 文件上传到 MinIO

1. 控制器(Controller)

java 复制代码
package com.donglin.file.controller;


import com.donglin.file.entity.BucketType;
import com.donglin.file.service.FileUploadService;
import com.donglin.result.Result;
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 FileController {

    @Autowired
    private FileUploadService fileUploadService;

    @PostMapping("/upload/public")
    public String uploadPublic(@RequestParam MultipartFile file) {
        return fileUploadService.upload(file, BucketType.PUBLIC);
    }

    @PostMapping("/upload/private")
    public String uploadPrivate(@RequestParam MultipartFile file) {
        return fileUploadService.upload(file, BucketType.PRIVATE);
    }
}

2. Service 接口

java 复制代码
package com.donglin.file.service;

import com.donglin.file.entity.BucketType;
import org.springframework.web.multipart.MultipartFile;

public interface FileUploadService {

    String upload(MultipartFile file, BucketType aPrivate);
}

3. Service 实现类

java 复制代码
package com.donglin.file.service.impl;

import com.donglin.file.entity.BucketType;
import com.donglin.file.entity.MinioConstantProperties;
import com.donglin.file.service.FileUploadService;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.UUID;

@Service
public class FileUploadServiceImol implements FileUploadService {
    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConstantProperties prop;

    @Override
    public String upload(MultipartFile file, BucketType bucketType) {

        try {
            // 1. 选择 bucket
            String bucket = bucketType == BucketType.PUBLIC
                    ? prop.getPublicBucket()
                    : prop.getPrivateBucket();

            // 2. 文件后缀
            String ext = FilenameUtils.getExtension(file.getOriginalFilename());

            // 3. 对象名(分目录)
            String objectName = String.format(
                    "%s/%s/%s.%s",
                    bucketType.name().toLowerCase(),
                    java.time.LocalDate.now(),
                    UUID.randomUUID().toString().replace("-", ""),
                    ext
            );

            // 4. 上传
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucket)
                            .object(objectName)
                            .stream(file.getInputStream(), file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build()
            );

            // 5. public:返回直链
            if (bucketType == BucketType.PUBLIC) {
                return prop.getEndpointUrl()
                        + "/" + bucket
                        + "/" + objectName;
            }

            // 6. private:返回预签名 URL
            return minioClient.getPresignedObjectUrl(
                    io.minio.GetPresignedObjectUrlArgs.builder()
                            .method(io.minio.http.Method.GET)
                            .bucket(bucket)
                            .object(objectName)
                            .expiry(1 * 60)
                            .build()
            );

        } catch (Exception e) {
            throw new RuntimeException("文件上传失败", e);
        }
    }
}

4. MinIO 配置类

java 复制代码
package com.donglin.file.entity;

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

@Configuration
@ConfigurationProperties(prefix = "minio")
@Data
public class MinioConstantProperties {

    // MinIO 服务地址
    private String endpointUrl;

    // AccessKey
    private String accessKey;

    // SecretKey
    private String secretKey;

    // Bucket 名称
    private String bucketName;

    // public / private bucket
    private String publicBucket;
    private String privateBucket;
}
csharp 复制代码
package com.donglin.file.entity;

public enum BucketType {
    PUBLIC,
    PRIVATE
}

config配置类

csharp 复制代码
package com.donglin.file.config;

import com.donglin.file.entity.MinioConstantProperties;
import io.minio.MinioClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MinioConfig {

    @Bean
    public MinioClient minioClient(MinioConstantProperties prop) {
        return MinioClient.builder()
                .endpoint(prop.getEndpointUrl())
                .credentials(prop.getAccessKey(), prop.getSecretKey())
                .build();
    }
}

yml

csharp 复制代码
minio:
  endpoint-url: http://192.168.121.140:9000
  access-key: admin
  secret-key: admin123456
  public-bucket: sky-public
  private-bucket: sky-private
server:
  port: 9600

把sky-public设置成public公有

结果

公共存储,一直能看

私有存储,目前设置的只能看1分钟


六、总结

  • MinIO 是一个 高性能、轻量级、S3 兼容 的对象存储服务

  • 非常适合:

    • 微服务项目
    • 图片 / 音视频存储
    • 日志与备份系统
  • 使用 Docker + Spring Boot 可快速落地

  • 注意 服务器时间同步,否则容易踩坑

相关推荐
VX:Fegn089518 分钟前
计算机毕业设计|基于springboot + vue酒店管理系统(源码+数据库+文档)
vue.js·spring boot·课程设计
qq_229058011 小时前
docker中检测进程的内存使用量
java·docker·容器
java_logo1 小时前
使用 Docker 部署 Clawdbot(官方推荐方式)
docker·容器·clawdbot·clawdbot部署·clawdbot部署手册·clawdbot部署文档·docker clawdbot
玉树临风江流儿2 小时前
docker镜像加速器配置步骤
运维·docker·容器
Java天梯之路2 小时前
Spring Boot 钩子全集实战(七):BeanFactoryPostProcessor详解
java·spring boot·后端
短剑重铸之日3 小时前
《SpringCloud实用版》生产部署:Docker + Kubernetes + GraalVM 原生镜像 完整方案
后端·spring cloud·docker·kubernetes·graalvm
露天赏雪4 小时前
Java 高并发编程实战:从线程池到分布式锁,解决生产环境并发问题
java·开发语言·spring boot·分布式·后端·mysql
lots洋4 小时前
使用docker-compose安装mysql+redis+nacos
redis·mysql·docker
GHL2842710905 小时前
Docker Desktop 启动报错“Virtualization support not detected“
c++·docker·容器
iRuriCatt5 小时前
智慧景区管理系统 | 计算机毕设项目
java·前端·spring boot·vue·毕设