Minio7.x的部署(docker)+springboot2.x整合Minio7.x
一.为什么选择Minio
简介:分布式文件存储常见解决方案介绍
- 目前业界比较多这个解决方案,这边就挑选几个介绍下
- MinIO
是在 Apache License v2.0 下发布的对象存储服务器,学习成本低,安装运维简单,主流语言的客户端整合都有, 号称最强的对象存储文件服务器,且可以和容器化技术docker/k8s等结合,社区活跃但不够成熟,业界参考资料较少
官网:https://docs.min.io/cn/
- FastDFS
一个开源的轻量级分布式文件系统,比较少的客户端可以整合,目前主要是C和java客户端,在一些互联网创业公司中有应用比较多,没有官方文档,社区不怎么活跃.
架构+部署结构复杂,出问题定位比较难定位,可以说是fastdfs零件的组装过程,需要去理解fastDFS的架构设计,才能够正确的安装部署
- 云厂商
- 阿里云OSS
- 七牛云
- 腾讯云
- 亚马逊云
- CDN最强:Akamai https://www.akamai.com/cn
- 选云厂商理由
- 优点:开发简单,功能强大,容易维护(不同网络下图片质量、水印、加密策略、扩容、加速)
- 缺点:要钱, 个性化处理,未来转移比较复杂,不排除有些厂商会提供一键迁移工具
- 选开源MinIO的理由
- 优点:功能强大、可以根据业务做二次的定制,新一代分布式文件存储系统,容器化结合强大,更重要的是免费(购买磁盘、内存、带宽)
- 缺点:自己需要有专门的团队进行维护、扩容等
注:更多理论知识需自行补充
二.Minio在Centos7.x中骨架搭建
所需配置不高:
CPU&内存1 核1GiB
操作系统 CentOS 7.8 64位
实例规格 ecs.t5-lc1m1.small(性能约束实例)
实例规格族 ecs.t5
云盘1
当前使用带宽 1Mbps
1.安装docker
#依次运行以下命令添加yum源
yum update
yum install epel-release -y
yum clean all
yum list#安装并运行Docker。
yum install docker-io -y
systemctl start docker#检查安装结果。
docker info#启动使用Docker
systemctl start docker #运行Docker守护进程
systemctl stop docker #停止Docker守护进程
systemctl restart docker #重启Docker守护进程#修改镜像仓库
vim /etc/docker/daemon.json
#改为下面内容,然后重启docker
{
“debug”:true,“experimental”:true,
“registry-mirrors”:[“https://xxx.mirror.aliyuncs.com”,“https://hub-mirror.c.163.com”,“https://docker.mirrors.ustc.edu.cn”]
}#查看信息
docker info
2.部署minio单节点(docker部署)
docker run -p 9000:9000
–name minio_x
-v /Users/xx/Desktop/test:/data
-e “MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE”
-e “MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY”
minio/minio server /data
3.安装docker-compose
安装docker-compose
yum install -y python-pip
curl -L https://github.com/docker/compose/releases/download/1.25.1/run.sh > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version
4.伪分布式部署minio集群(docker-compose部署)
vim docker-compose.yml
# starts 4 docker containers running minio server instances. Each
# minio server's web interface will be accessible on the host at port
# 9001 through 9004.
services:
minio1:
image: minio/minio
volumes:
- data1-1:/data1
- data1-2:/data2
ports:
- "9001:9000"
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio2:
image: minio/minio
volumes:
- data2-1:/data1
- data2-2:/data2
ports:
- "9002:9000"
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio3:
image: minio/minio
volumes:
- data3-1:/data1
- data3-2:/data2
ports:
- "9003:9000"
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio4:
image: minio/minio
volumes:
- data4-1:/data1
- data4-2:/data2
ports:
- "9004:9000"
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
## By default this config uses default local driver,
## For custom volumes replace with volume driver configuration.
volumes:
data1-1:
data1-2:
data2-1:
data2-2:
data3-1:
data3-2:
data4-1:
data4-2:
docker-compose up
5.多服务器部署minio集群(docker-compose部署)
说明:此项目只用了4个节点8个分区,根据需要可以自行扩展使用
修改hosts文件4个节点均需要修改 vi /etc/hosts
172.18.29.152 minio-node-1
172.18.29.150 minio-node-2
172.18.29.153 minio-node-3
172.18.29.151 minio-node-4
vim docker-compose.yml
节点4:
version: '3.7'
# starts 4 docker containers running minio server instances. Each
# minio server's web interface will be accessible on the host at port
# 9001 through 9004.
services:
minio-node:
image: minio/minio
network_mode: "host"
volumes:
- /root/data4-1:/data1
- /root/data4-2:/data2
# ports:
# - "9001:9000"
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
command: server http://minio-node-{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
节点3:
version: '3.7'
# starts 4 docker containers running minio server instances. Each
# minio server's web interface will be accessible on the host at port
# 9001 through 9004.
services:
minio-node:
image: minio/minio
network_mode: "host"
volumes:
- /root/data3-1:/data1
- /root/data3-2:/data2
# ports:
# - "9001:9000"
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
command: server http://minio-node-{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
节点2:
version: '3.7'
# starts 4 docker containers running minio server instances. Each
# minio server's web interface will be accessible on the host at port
# 9001 through 9004.
services:
minio-node:
image: minio/minio
network_mode: "host"
volumes:
- /root/data2-1:/data1
- /root/data2-2:/data2
# ports:
# - "9001:9000"
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
command: server http://minio-node-{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
节点1:
version: '3.7'
# starts 4 docker containers running minio server instances. Each
# minio server's web interface will be accessible on the host at port
# 9001 through 9004.
services:
minio-node:
image: minio/minio
network_mode: "host"
volumes:
- /root/data1-1:/data1
- /root/data1-2:/data2
# ports:
# - "9001:9000"
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
command: server http://minio-node-{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
也可用过scp命令进行快速传送配置文件
scp docker-compose.yml root@ip:/root
注:第一次启动集群需要所有存储路径为空
通过docker-compose up启动4个节点
出现面内容说明启动成功
[root@iZ2ze8tuatzv94fm6fgl1mZ ~]# docker-compose up
WARNING: Found orphan containers (root_minio-node-4_1, root_minio3_1, root_minio4_1, root_minio1_1, root_minio2_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Recreating root_minio-node_1 ... done
Attaching to root_minio-node_1
minio-node_1 | Waiting for all MinIO sub-systems to be initialized.. lock acquired
minio-node_1 | All MinIO sub-systems initialized successfully
minio-node_1 | Status: 8 Online, 0 Offline.
minio-node_1 | Endpoint: http://172.18.29.151:9000 http://172.17.0.1:9000 http://172.19.0.1:9000 http://127.0.0.1:9000
minio-node_1 |
minio-node_1 | Browser Access:
minio-node_1 | http://172.18.29.151:9000 http://172.17.0.1:9000 http://172.19.0.1:9000 http://127.0.0.1:9000
minio-node_1 |
minio-node_1 | Object API (Amazon S3 compatible):
minio-node_1 | Go: https://docs.min.io/docs/golang-client-quickstart-guide
minio-node_1 | Java: https://docs.min.io/docs/java-client-quickstart-guide
minio-node_1 | Python: https://docs.min.io/docs/python-client-quickstart-guide
minio-node_1 | JavaScript: https://docs.min.io/docs/javascript-client-quickstart-guide
minio-node_1 | .NET: https://docs.min.io/docs/dotnet-client-quickstart-guide
minio-node_1 | Detected default credentials 'minioadmin:minioadmin', please change the credentials immediately using 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD'
minio-node_1 | Waiting for all MinIO IAM sub-system to be initialized.. lock acquired
三.nginx实现负载均衡
四.springboot整合Minio
1.添加Maven依赖
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>xxx</groupId>
<artifactId>xx-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.1.0</version>
</dependency>
</dependencies>
</project>
2.yml配置:(.properties类似)
#配置文件上传限制策略
servlet:
multipart:
max-file-size: 200MB
max-request-size: 200MB
#MinIO配置
minio:
endpoint: http://8.131.119.1:xxxx
access-key-id: AKIAIOSFODNN7EXAMPLE
access-key-secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
bucketname: aaa
3.配置类:
package net.xx.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;
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketname;
@Bean
public MinioClient minioClient(){
//创建minio对象
MinioClient minioClient = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKeyId,accessKeySecret).build();
return minioClient;
}
}
4上传文件:(根据需求自行修改)
@Component
@Slf4j
public class MinIOComponent {
@Autowired
private MinioConfig minioConfig;
@Autowired
private MinioClient minioClient;
/**
* 文件上传
* @param file
* @return
*/
public String uploadFile(MultipartFile file){
//获取相关配置
String bucketname = minioConfig.getBucketname();
String endpoint = minioConfig.getEndpoint();
String accessKeyId = minioConfig.getAccessKeyId();
String accesskeySecret = minioConfig.getAccessKeySecret();
//获取原生文件名 xxx.jpg
String originalFilename = file.getOriginalFilename();
//JDK8的日期格式化
LocalDateTime ldt = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
//拼装路径,上存储的路径 2021/2/14/xxxx.jpg
//2021/2/5/
String folder = dtf.format(ldt);
//xxxx
String fileName = CommonUtil.generateUUID();
//.jpg
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
//新文件名
String newFileName = "user/"+folder+"/"+fileName+extension;
try (InputStream inputStream = file.getInputStream()){
ObjectWriteResponse putObject = minioClient.putObject(PutObjectArgs.builder()
.bucket(bucketname)
.object(newFileName)
.stream(inputStream, file.getSize(), -1)
.contentType(file.getContentType())
.build());
if(putObject!=null){
//String imgUrl = minioClient.getObjectUrl(bucketname,newFileName);
String imgUrl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketname).object(newFileName).build());
return imgUrl;
}
} catch (Exception e) {
log.error("文件上传失败:{}",e);
}
return null;
}
5.删除文件
/**
* 删除头像
* @param attachmentNameInServer
* @return
*/
@Override
public boolean delUserImg(String attachmentNameInServer) {
// String[] strArr = url.substring(0,url.indexOf('?')).split("/");
// String fileName = strArr[strArr.length-1];
try {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(minioConfig.getBucketname()).object(attachmentNameInServer).build());
return true;
}catch (Exception e){
log.warn("fileName 文件删除异常:{}",e);
return false;
}
}