一、了解MinIO
MinIO 是一个高性能的分布式对象存储服务器,兼容 Amazon S3 API,具有以下特点:
-
高性能:针对存储和检索优化
-
轻量级:单个二进制文件即可运行
-
云原生:支持 Kubernetes 部署
-
S3 兼容:可以直接替换 AWS S3
-
数据保护:纠删码和加密支持
核心组件
-
MinIO Server:存储服务主体
-
MinIO Client (mc):命令行管理工具
-
MinIO Console:Web 管理界面
二、搭建MinIO
以下两个方法用一个就行,笔者用docker
2.1Linux命令搭建
# 下载二进制文件
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/
# 创建数据目录
sudo mkdir -p /data/minio
sudo chown -R $USER:$USER /data/minio
# 启动服务(前台运行)
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=your-strong-password
minio server /data/minio --console-address ":9001"
2.2docker容器搭建
创建mkdir -p mnt/data并保证改文件可被写入
docker拉取docker pull minio/minio:RELEASE.2023-04-28T18-11-17Z
[root@VM-20-2-centos ~]# docker pull minio/minio:RELEASE.2023-04-28T18-11-17Z
Trying to pull repository docker.io/minio/minio ...
RELEASE.2023-04-28T18-11-17Z: Pulling from docker.io/minio/minio
28ff5ee6facb: Pull complete
3693dff23ec8: Pull complete
5704174bdb96: Pull complete
d508ad7e7f9a: Pull complete
afe65f7a1e28: Pull complete
749650377f44: Pull complete
Digest: sha256:8ba4ed4d0eafe0458071c2ebe12301eaccd32b10d5299765db2b00ef2f1b382b
Status: Downloaded newer image for docker.io/minio/minio:RELEASE.2023-04-28T18-11-17Z
防火墙和服务器开启端口
sudo firewall-cmd --permanent --add-port=9000-9002/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports
dcoker运行minio
密码至少8位
[root@VM-20-2-centos ~]# docker run -d \
> -p 9000:9000 \
> -p 9001:9001 \
> --name minio \
> -v /mnt/data:/data \
> -e "MINIO_ROOT_USER=admin" \
> -e "MINIO_ROOT_PASSWORD=12345678" \
> minio/minio:RELEASE.2023-04-28T18-11-17Z \
> server /data --console-address ":9001"
ed3f142e91657b66ab3264f7f3df70327efdd1c15334d06217e5a919d9297e74
查看是否运行成功
三、使用MinIO
http://服务器公网地址:9001 输入运行minio时设置的账号和密码
新建桶
四、 MinIO整合springboot项目
4.1导入配置文件
先只导入minio,报错再试试加上okhttp,不是所有人都需要额外指定okhttp
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.11</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version> <!-- 使用最新稳定版 -->
</dependency>
application.yml
minio:
endpoint: http://82.157.170.39:9000
access-key: admin
secret-key: 12345678
bucket-name: bucket
4.2创建方法
MinioConfig
package com.hl.mybatisplus;
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MinioConfig {
@Value("${minio.endpoint}")
private String endpoint;
@Value("${minio.access-key}")
private String accessKey;
@Value("${minio.secret-key}")
private String secretKey;
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
}
}
MinioService
package com.hl.mybatisplus;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@Service
public class MinioService {
@Autowired
private MinioClient minioClient;
@Value("${minio.bucket-name}")
private String bucketName;
public String uploadFile(MultipartFile file) throws Exception {
// 检查存储桶是否存在,不存在则创建
boolean found = minioClient.bucketExists(BucketExistsArgs.builder()
.bucket(bucketName)
.build());
if (!found) {
minioClient.makeBucket(MakeBucketArgs.builder()
.bucket(bucketName)
.build());
}
// 上传文件
String objectName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(file.getInputStream(), file.getSize(), -1)
.contentType(file.getContentType())
.build());
return objectName; // 返回文件在 MinIO 中的唯一标识
}
}
FileUploadController
package com.hl.mybatisplus;
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 {
@Autowired
private MinioService minioService;
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
try {
return minioService.uploadFile(file);
} catch (Exception e) {
return "上传失败: " + e.getMessage();
}
}
}