快速上手java

[minio安装配置教程及整合springboot(史上最强保姆级教程—minio入门)_minio配置-CSDN博客](https://blog.csdn.net/qq_51073233/article/details/127673489#:~:text=minio安装配置教程及整合springboot(史上最强保姆级教程---minio入门) 1 1、进入minio官网 2 2、选择放置minio文件路径 3 3、根据命令行提示访问minio面板,4 4、minio配置(yaml文件版) 5 5、编写minio的配置文件MinIoClientConfig 6 6、新建minio工具类需要的实体类ObjectItem 7 7、编写minio的工具类MinioUtils)

我这里直接把它的搬运过来了😜

这些建议弄完docker 部署在来搞

依赖引入

1
2
3
4
5
6
<!-- 高版本的会报okhttp不兼容-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.2</version>
</dependency>

yaml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
# 配置文件上传大小限制(minio文件上传)
servlet:
multipart:
max-file-size: 500MB
max-request-size: 500MB

minio:
endpoint: http://localhost:9000
accessKey: minioadmin
secretKey: minioadmin
# 文件夹的名字(如果没有需要可以先到界面端端口创建)
bucketName: community-web

Config 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.demo.javatest.config;

import io.minio.MinioClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Data
@Component
public class MinIoClientConfig {
@Value("${minio.endpoint}")
private String endpoint;
@Value("${minio.accessKey}")
private String accessKey;
@Value("${minio.secretKey}")
private String secretKey;


/**
* 注入minio 客户端
*
* @return
*/
@Bean
public MinioClient minioClient() {

return MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
}
}

entity

1
2
3
4
5
6
7
8
9
10
11
package com.demo.javatest.entity;

import lombok.Data;

@Data
public class ObjectItem {
private String objectName;
private Long size;
}


utils

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
package com.demo.javatest.utils;


import com.demo.javatest.entity.ObjectItem;
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
* @description: minio工具类
* @version:1.0
*/
@Component
public class MinioUtils {
@Autowired
private MinioClient minioClient;

@Value("${minio.bucketName}")
private String bucketName;

/**
* description: 判断bucket是否存在,不存在则创建
*
* @return: void
*/
public void existBucket(String name) {
try {
boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());
if (!exists) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());
}
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 创建存储bucket
*
* @param bucketName 存储bucket名称
* @return Boolean
*/
public Boolean makeBucket(String bucketName) {
try {
minioClient.makeBucket(MakeBucketArgs.builder()
.bucket(bucketName)
.build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}

/**
* 删除存储bucket
*
* @param bucketName 存储bucket名称
* @return Boolean
*/
public Boolean removeBucket(String bucketName) {
try {
minioClient.removeBucket(RemoveBucketArgs.builder()
.bucket(bucketName)
.build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}

/**
* description: 上传文件
*
* @param multipartFile
* @return: java.lang.String
*/
public List<String> upload(MultipartFile[] multipartFile) {
List<String> names = new ArrayList<>(multipartFile.length);
for (MultipartFile file : multipartFile) {
String fileName = file.getOriginalFilename();
String[] split = fileName.split("\\.");
if (split.length > 1) {
fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1];
} else {
fileName = fileName + System.currentTimeMillis();
}
InputStream in = null;
try {
in = file.getInputStream();
minioClient.putObject(PutObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.stream(in, in.available(), -1)
.contentType(file.getContentType())
.build()
);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
names.add(fileName);
}
return names;
}

/**
* description: 下载文件
*
* @param fileName
* @return: org.springframework.http.ResponseEntity<byte [ ]>
*/
public ResponseEntity<byte[]> download(String fileName) {
ResponseEntity<byte[]> responseEntity = null;
InputStream in = null;
ByteArrayOutputStream out = null;
try {
in = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
out = new ByteArrayOutputStream();
IOUtils.copy(in, out);
//封装返回值
byte[] bytes = out.toByteArray();
HttpHeaders headers = new HttpHeaders();
try {
headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
headers.setContentLength(bytes.length);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setAccessControlExposeHeaders(Arrays.asList("*"));
responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return responseEntity;
}

/**
* 查看文件对象
*
* @param bucketName 存储bucket名称
* @return 存储bucket内文件对象信息
*/
public List<ObjectItem> listObjects(String bucketName) {
Iterable<Result<Item>> results = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucketName).build());
List<ObjectItem> objectItems = new ArrayList<>();
try {
for (Result<Item> result : results) {
Item item = result.get();
ObjectItem objectItem = new ObjectItem();
objectItem.setObjectName(item.objectName());
objectItem.setSize(item.size());
objectItems.add(objectItem);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return objectItems;
}

/**
* 批量删除文件对象
*
* @param bucketName 存储bucket名称
* @param objects 对象名称集合
*/
public Iterable<Result<DeleteError>> removeObjects(String bucketName, List<String> objects) {
List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
// 判断是否出现文件删除错误
// for (Result<DeleteError> result : results) {
// DeleteError deleteError = null;
// try {
// deleteError = result.get();
// } catch (ErrorResponseException e) {
// throw new RuntimeException(e);
// } catch (InsufficientDataException e) {
// throw new RuntimeException(e);
// } catch (InternalException e) {
// throw new RuntimeException(e);
// } catch (InvalidKeyException e) {
// throw new RuntimeException(e);
// } catch (InvalidResponseException e) {
// throw new RuntimeException(e);
// } catch (IOException e) {
// throw new RuntimeException(e);
// } catch (NoSuchAlgorithmException e) {
// throw new RuntimeException(e);
// } catch (ServerException e) {
// throw new RuntimeException(e);
// } catch (XmlParserException e) {
// throw new RuntimeException(e);
// }
// System.out.println(deleteError);
// }
return results;
}
}



controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.demo.javatest.controller;


import com.demo.javatest.utils.MinioUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

@RestController
@Slf4j
public class MinioController {
@Autowired
private MinioUtils minioUtils;
@Value("${minio.endpoint}")
private String address;
@Value("${minio.bucketName}")
private String bucketName;

@PostMapping("/upload")
public Object upload(MultipartFile file) {

List<String> upload = minioUtils.upload(new MultipartFile[]{file});

return address + "/" + bucketName + "/" + upload.get(0);
}
@DeleteMapping("/delete")
public Object delete(String bucketName, String fileName){
List<String> list = new ArrayList<>();
list.add(fileName);
// return ;

return minioUtils.removeObjects(bucketName, list);
}
@PostMapping("/get")
public Object get(String name){
return minioUtils.download(name);
}
@GetMapping("/makeBucket")
public Object makeBucket(String bucketName){
return minioUtils.makeBucket(bucketName);
}
}

测试实例

  • 上传

image-20231211112944485

  • 删除

image-20231211113004313

  • 下载image-20231211113021621
  • 创建minio文件夹

image-20231211113037848

前言

  • 他封装了一系列的指令, 所以特别的有用啊, 当然我们到时候是要学java

image-20231208202712873

分布式文件系统应用场景

image-20231208202941064

  • 优点

image-20231208204051612

基础介绍

基础概念

  • bucket :(顶层目录)不同项目可以使用不同的bucket 分隔开
  • Object:存储到Minio的基本对象,比如文件,字节流
  • Drive:存储数据的磁盘,再Minio启动时,以参数的方式传入,Minio中所有的对象数据都被存储到Drive中
  • set:就是Drive的集合
    • 一个集群可以划分出多个set
    • 一个对象存储在一个set中

纠删码(EC)

  • BIT Rot Protection 处理数据损坏

image-20231208204418998

存储形式

奇数, 偶数存储法, 奇数和偶数分别存储的是编码前,和编码后的文件, 前者为 编码数据块以及校验块、后者是元数据文件

环境搭建

  • centos7 和 docker单机部署

单机部署

  • 比较适合学习
1
2
3
4
5
6
7
8
9
wget https://dl.minio.org.cn/server/minio/release/linux-amd64/minio
# 添加执行权限
chmod +x minio
sudo mv minio /docker/minio/

# 移动到对应目录
cd /docker/minio/
# /mnt/data 磁盘位置
./minio server /mnt/data
  • 进入测试阶段

image-20231208210242943

46446是界面端口, 9000是真正访问数据的端口

需要注意的是,如果你是用远程服务器弄的,它给你的是内网的ip地址,你访问的时候访问外网的即可

image-20231208210731740

修改用户和密码设置静态端

image-20231208210927889

1
2
3
4
5
6
7
8
# 修改用户名和密码 (注意你的用户名长度至少是3位, 密码至少是8位
export MINIO_ROOT_USER=root
export MINIO_ROOT_PASSWORD=114514114514

# 修改配置文件路径(这个看你自己的想法来修改)
./minio server --config-dir /mnt/config /mnt/data
# 设置静态端口
./minio server --console-address ":44619" /mnt/data
  • 但是这个是没有EC模式的, 数据不安全

docker 部署

1
2
3
4
5
6
docker run -d -p 9000:9000 -p 44619:44619 --name minio \
-e "MINIO_ROOT_USER=root" \
-e "MINIO_ROOT_PASSWORD=114514114514" \
-v /mnt/data:/data \
-v /mnt/config:/root/.minio \
minio/minio server --console-address ":44619" /data

具有纠删码功能部署

image-20231209202808161

  • 再minio 中一个block 就是10MB
  • 如果一个文件有多个block 就会把他拆分
1
2
3
4
5
6
7
8
9
10
11
12
docker run -d -p 9000:9000 -p 44619:44619 --name minio \	
-v /mnt/data1:/data1 \
-v /mnt/data2:/data2 \
-v /mnt/data3:/data3 \
-v /mnt/data4:/data4 \
-v /mnt/data5:/data5 \
-v /mnt/data6:/data6 \
-v /mnt/data7:/data7 \
-v /mnt/data8:/data8 \
minio/minio server /data{1...8} --console-address ":44619"

# tree, 你要添加文件之后, tree才有作用

Minio 分布式

Minio 客户端设置

1
2
3
4
wget http://dl.minio.org.cn/client/mc/release/linux-amd64/mc

chmod +x mc
mv mc /docker/minio

指令

略(有时间再看)

  • mc config 查看配置

  • mc config host ls 查看所有的ip主机地址

image-20231209205437045