一,背景
项目中用到图片和文件的存储及展示,之前部署在阿里云的OSS,因为贫穷问题,从OSS换成自己部署一套文件服务器。在FastDFS和MinIO中选型了后者,开箱即用,比较方便。这里记录并分享下安装部署及使用的方案。
二,安装
jdk的安装和部署这里就不提了吧。我用的是jdk1.8
然后MinIO的安装非常简单,直接官网下载直接用dnf install装。
dnf install https://dl.minio.org.cn/server/minio/release/linux-amd64/minio-20230804174021.0.0.x86_64.rpm
安装结束,一步即可,巴适吧。
可以先按照官网建议的,临时启动看看效果。
MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password minio server /mnt/data --console-address ":9001"
将会提示:
[root@localhost ~]# MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password minio server /mnt/data --console-address ":9001"
WARNING: Detected Linux kernel version older than 4.0.0 release, there are some known potential performance problems with this kernel version. MinIO recommends a minimum of 4.x.x linux kernel version for best performance
MinIO Object Storage Server
Copyright: 2015-2023 MinIO, Inc.
License: GNU AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html>
Version: RELEASE.2023-08-04T17-40-21Z (go1.19.12 linux/amd64)
Status: 1 Online, 0 Offline.
S3-API: http://192.168.226.152:9000 http://127.0.0.1:9000
RootUser: admin
RootPass: password
Console: http://192.168.226.152:9001 http://127.0.0.1:9001
RootUser: admin
RootPass: password
Command-line: https://min.io/docs/minio/linux/reference/minio-mc.html#quickstart
$ mc alias set myminio http://192.168.226.152:9000 admin password
Documentation: https://min.io/docs/minio/linux/index.html
我们回到自己电脑上,访问http://192.168.226.152:9001,用户名和密码就是刚才输入的admin和password
进去后,就可以创建bucket啦,是不是非常简单,开箱即用咧?
三,部署
刚才我们只是用临时命令启动了,发现ctrl+c就退出了。
1,所以我们还要动动小手,把minio改成服务式的。
也很简单,只要写个在system下新建个服务脚本文件即可
vim /etc/systemd/system/minio.service
[Unit]
Description=MinIO Server
After=network.target
[Service]
ExecStart=/usr/local/bin/minio server /mnt/data --console-address ":9001"
#这里不建议用root账号
User=minio
Restart=always
#下面2个就是web端管理工具的账号
Environment=MINIO_ROOT_USER=admin
#这里的密码长度和复杂度没看到什么要求,但是实际我发现低于8位可能会启动失败
Environment=MINIO_ROOT_PASSWORD=password
#下面是限制每个文件是大小为10M
Environment=MINIO_MAX_UPLOAD_SIZE=10MB
[Install]
WantedBy=multi-user.target
创建一个名为 minio
的系统用户,并禁止这个用户登录。
sudo useradd -r -s /bin/false minio
判断该用户是否创建成功或者是否存在,可以用
id minio
或者
grep minio/etc/passwd
记得要给minio用户权限
sudo chown -R minio:minio /mnt/data
2,配置文件里设置了每个文件的大小是10M,那么bucket的容量最大值在哪里设置呢?
要限制特定存储桶或整个MinIO服务器的存储空间,以避免磁盘空间被填满,你可以使用MinIO的 quota功能。quota功能允许你设置存储桶或整个MinIO服务器中存储对象的总大小限制。 以下是如何使用 quota功能设置存储空间限制的步骤: 1. 为特定存储桶设置存储空间限制: - 打开MinIO的Web管理界面,进入所需的存储桶。 - 点击"Bucket Policy"选项卡。 - 在"Bucket Policy"部分,点击"Edit Policy"。 - 添加以下策略来设置存储空间限制(将 <bucket-name>
和 <size-limit>
替换为你的值):
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:CopyObject"
],
"Effect": "Deny",
"Principal": "*",
"Resource": [
"arn:aws:s3:::<bucket-name>/*"
],
"Condition": {
"NumericGreaterThanEquals": {
"s3:object-size": "<size-limit>"
}
}
}
]
}
然后保存策略。
3,如果我们需要为整个MinIO服务器设置存储空间限制:
打开MinIO的Web管理界面,进入"Global Policy"选项卡。 - 在"Global Policy"部分,点击"Edit Policy"。 - 添加以下策略来设置存储空间限制(将 <size-limit>
替换为你的值):
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:CopyObject"
],
"Effect": "Deny",
"Principal": "*",
"Resource": "*",
"Condition": {
"NumericGreaterThanEquals": {
"s3:object-size": "<size-limit>"
}
}
}
]
}
然后保存策略。
通过设置这些策略,任何超过指定大小限制的上传或复制对象的尝试都将被拒绝。 请注意,上述指令是基于你使用MinIO的Web管理界面的假设。如果你更喜欢通过编程或命令行界面配置配额,你可以参考MinIO文档,了解如何使用MinIO API或 MC工具来设置配额。
记得根据你的具体需求调整 <bucket-name>
和 <size-limit>
的占位符。
4,还有个需要提下,我们部分场景下有对涉密的一些文件的分享链接有时效性要求。
我们使用MC工具设置共享链接的过期时间。例如,如果要将名为 "myobject" 的共享链接在存储桶 "mybucket" 中设置为7天的过期时间,可以使用以下命令:
#要先装minio client,这里不具体交代了,因为我不打算装了
mc share upload --expire 7d mybucket/myobject
5,启动啦
如果我们修改了上面提到的minio.service脚本内容,需要在启动之前先:
sudo systemctl daemon-reload
然后还是服务启动的那几个常规老命令了
sudo systemctl start minio
sudo systemctl restart minio
sudo systemctl stop minio
sudo systemctl status minio
sudo systemctl enable minio
#这几条命令就不多解释了吧
启动后如果发现新修改的minio.service脚本内容没生效
首先先重新systemctl daemon-reload,再restart。如果还是无效就先stop minio,然后
#先停服务
sudo systemctl stop minio
#删除 ~/.minio/config 文件
rm ~/.minio/config
#再启动
sudo systemctl start minio
#等待几秒钟,检查相关参数生效
6,防火墙打开
#防火墙打开和重载
firewall-cmd --add-port=9001/tcp --permanent
firewall-cmd --reload
# 安装net-tools
yum install -y net-tools
# 检查9001是否有监听
netstat -antp |grep 9001
一般9000是程序调用时读写文件的端口,9001是web管理工具的端口,具体也可以改就是了。
7,检查9001管理工具,正常。部署完毕
四,spring boot应用minio
在9001管理工具里新建一个bucket,新建一组access key,咱们就可以通过java来存、读文件了。
1,首先pom,官网时令推荐的是8.4.3,我用了后运行有异常,降低到7.0.2就正常了。原因不确定,可能和jdk(我1.8)、spring boot(我2.6.13)的版本兼容性有关系吧。
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.4.3</version>
</dependency>
2,然后直接代码了。注意这里有个小坑,就是本机与服务器之间的时间差异不能过大,否则会造成api使用报错:
ErrorResponse(code = RequestTimeTooSkewed, message = The difference between the request time and the server's time is too large., bucketName = null, objectName = null, resource = /mybucket.........
try {
String accessKey = "改成你的";
String secretKey = "改成你的";
String endpoint = "http://你的ip:9000";
String bucketName = "mybucket";
// 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
MinioClient minioClient = new MinioClient(endpoint, accessKey, secretKey);
// 检查存储桶是否已经存在
String test_bucketName = "mybucket";
boolean isExist = minioClient.bucketExists(test_bucketName);
System.out.println(isExist);
if (!isExist) {
minioClient.makeBucket(test_bucketName);
}
// 移除存储桶
// minioClient.removeBucket(test_bucketName);
// 遍历所有桶
List<Bucket> buckets = minioClient.listBuckets();
if (buckets != null && !buckets.isEmpty()) {
buckets.forEach(bucket -> {
System.out.println(bucket.name());
});
}
String objectName = "Test/test.jpg";
// 使用putObject上传一个文件到存储桶中。
File file = new File("C:\\Users\\Administrator\\Desktop\\test.jpg");
InputStream is = new FileInputStream(file);
// 使用putObject上传一个本地文件到存储桶中。
minioClient.putObject(bucketName, objectName, is, new PutObjectOptions(is.available(), -1));
is.close();
// 获取对象url
String file_url = minioClient.getObjectUrl(bucketName, "test.jpg");
System.out.println(file_url);
// 删除对象
//minioClient.removeObject(bucketName, "test.jpg");
// 分享连接
String url = minioClient.presignedGetObject(bucketName, objectName, 60 * 60 * 24);
System.out.println(url);
System.out.println("ok");
return "hello minio:"+url;
} catch (Exception e) {
e.printStackTrace();
return "错啦:"+e;
3,验证
我们回到9007的管理工具里,可以看到mybucket/Test/test.jpg了。
成功!