当前位置:网站首页>Minio 入门
Minio 入门
2022-07-30 15:50:00 【Space Chars】
安装
Docker
docker run --name minio \
-d --restart=always \
-p 9000:9000 \
-p 9001:9001 \
--network tool-net --network-alias minio \
-e "MINIO_ACCESS_KEY=admin" \
-e "MINIO_SECRET_KEY=admin123456" \
-v minio_data:/data \
-v min_config:/root/.minio \
minio/minio server /data --console-address ":9001"
注意:
--console-address当前最新版必须指定控制台端口(浏览器页面访问端口),如果不指定,将会随机生成端口,不方便服务器开启防火墙- Minio 默认api addres 的端口是9000,浏览器访问9000端口时,会跳转到控制台端口
--console-address - 一定要将Minio的数据目录挂载到主机上,防止删除容器时,删除了储存的数据
控制台
进入控制台可以通过9000端口,他会自动跳转到控制台的9001端口,也可以直接通过9001端口进入控制台
登录
控台登录账户和密码是Docker 启动时的MINIO_ACCESS_KEY参数和MINIO_SECRET_KEY参数

桶
桶(Bucket):Minio 通过桶去存储文件,存储文件时需要指定目标桶才可以存储,
创建桶
点击Bucket->create bucket

配置桶
1. 基础信息
右侧有关于配置信息的解释
- Bucket Name: 桶名
- Version:开启统一对象多版本
- Object locking:对象锁:防止对象被删除,如果不设置
Retention,那么文件将不能被删除 - Quota:配额,限制桶内的对象数量
- Retention:保留策略,设置文件再桶内存活的周期,开启后
Object locking会自动开启,因为文件保留期间,对象是禁止删除的- Model:策略模式:1. Compliance:在
Validity天后被删除 2. Governance 在Validity天后删除在生命周期内未操作的对象 - Validity:生命周期:对象至少存活多少天
- Model:策略模式:1. Compliance:在

2. 桶内对象的操作策略
点击Bucket-->Manage--> Access Rules

上传后的对象名格式:
[Rule alias]_[Object Name].[文件后缀]
- Prefix:Rule 别名
- Access:决策

身份 Identity
身份管理
账户 Users
创建、管理Minio账户
账户组 Groups
对Minio用户进行分组
服务账户 Services Accounts
创建、管理服务账户
这里创建的账户,主要用于开发,也是最常用的

Create Service Account
- 点击
create service account,创建Service Account
Minio会自动创建键账户和密码,如果开发这需要配置使用权限,可开启下方的Restrict beyond user policy
- 点击create,会提示你保存密钥信息,个人建议下载密钥i信息,因为密钥是随机值,不方便记忆

使用
Spring boot
依赖
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.1</version>
</dependency>
配置类
MinIOProperties.java
Minio 参数 Properties类
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "minio")
public class MinIOProperties {
/** * 连接url */
private String endpoint;
/** * Service Account——accesskey */
private String accessKey;
/** * Service Account——secretKey */
private String secretKey;
/** * 桶 */
private String bucket;
/** * 分片大小 */
private long partSize=5 * 1024 * 1024;
}
MinIOHelper,java
Minio工具类,用于编写操作Minio的具体方法
该类在AutoConfig类中已注入到IOC容器中,方便开发者在service或controller中调用
import cn.hutool.core.util.ObjectUtil;
import io.minio.*;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import java.io.FileNotFoundException;
public class MinIOHelper {
@Autowired
private MinioClient client;
@Autowired
private MinIOProperties properties;
/** * 创建桶 * * @param bucketName 通名称 */
@SneakyThrows
public void createBucket(String bucketName) {
BucketExistsArgs bucket = BucketExistsArgs.builder().bucket(bucketName).build();
if (!client.bucketExists(bucket)) {
MakeBucketArgs make = MakeBucketArgs.builder().bucket(bucketName).build();
client.makeBucket(make);
}
}
/** * 上传文件 * * @param file 文件 * @param bucketName 存储桶 * @return */
public String uploadFile(MultipartFile file, String bucketName, FileRule rule) throws FileNotFoundException {
// 判断上传文件是否为空
if (ObjectUtil.isEmpty(file) || 0 == file.getSize()) {
throw new FileNotFoundException();
}
//检查桶名
if (ObjectUtil.isEmpty(bucketName)) {
bucketName = properties.getBucket();
if (ObjectUtil.isEmpty(bucketName)) {
throw new MinioUploadExecption("Bucket 必填");
}
}
if (ObjectUtil.isEmpty(rule)) {
rule = FileRule.READ_WRITE;
}
try {
// 判断存储桶是否存在
createBucket(bucketName);
// 文件名
String originalFilename = file.getOriginalFilename();
// 新的文件名 = 存储桶名称_时间戳.后缀名
String fileName = rule.getLabel() + "_" + System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf("."));
// 开始上传
PutObjectArgs build = PutObjectArgs.builder()
.bucket(bucketName)
.object(fileName)
.contentType(file.getContentType())
.stream(file.getInputStream(), file.getSize(), properties.getPartSize())
.build();
ObjectWriteResponse response = client.putObject(build);
return bucketName + "/" + fileName;
} catch (Exception e) {
throw new MinioUploadExecption("上传失败");
}
}
}
FileRule.java
该枚举类实现的是Bucket Access Rules配置内容,方便开发者调用,不在用于记忆前缀
public enum FileRule {
WRITE_ONLY(0, "w"),
READ_ONLY(1, "r"),
READ_WRITE(2,"r-w");
private Integer value;
private String label;
FileRule(Integer value, String label) {
this.value = value;
this.label = label;
}
public Integer getValue() {
return value;
}
public String getLabel() {
return label;
}
}
EnableOSS.java
Minio启动注解
将该类配置在对应服务的启动类上,即可
服务启动时spring 会自动去寻找@Import({MinIOAutoCondig.class})的自动配置类,从而实现自动配置
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
@Target({
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({
MinIOAutoCondig.class})
public @interface EnableOSS {
}
MinIOAutoCondig.java
Minio 自动配置类
因为Minio 本身就是未分布式微服务而设计的,所以必然存在多模块,而为了调用方便,所以本文使用启动注解加自动配置类的方式调用Minio
import cn.hutool.core.util.ObjectUtil;
import io.minio.MinioClient;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ConditionalOnClass({
MinioClient.class})
@Configuration
@EnableConfigurationProperties({
MinIOProperties.class})
public class MinIOAutoCondig {
@Autowired
private MinIOProperties minIOProperties;
private MinioClient client;
@Bean
public MinioClient minioClient() {
if (ObjectUtil.isEmpty(minIOProperties.getEndpoint())) {
throw new BeanCreationException("minio.endpoint don't null");
}
if (ObjectUtil.isEmpty(minIOProperties.getAccessKey())) {
throw new BeanCreationException("minio.access-key don't null");
}
if (ObjectUtil.isEmpty(minIOProperties.getSecretKey())) {
throw new BeanCreationException("minio.secret-key don't null");
}
client= MinioClient.builder().endpoint(minIOProperties.getEndpoint()).credentials(minIOProperties.getAccessKey(), minIOProperties.getSecretKey()).build();
return client;
}
@Bean
public MinIOHelper minIOHelper(){
return new MinIOHelper();
}
}
调用
Properties
minio.access-key、minio.secret-key分别对应的是Services Accounts 中创建的账户
minio.endpoint=http://xx.xx.xx.xx:9000
minio.bucket=client
minio.access-key=gutgSnXxxxxH2zgxxx
minio.secret-key=EOiOz9KFxxxxmaC8uGLxxxxQlJINVPSxxx
Controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.cxjfun.jdoc.client.server.vo.UploadFile;
import top.cxjfun.jdoc.common.CustomException;
import top.cxjfun.jdoc.common.db.oss.MinIOHelper;
import javax.servlet.http.HttpServletRequest;
import java.io.FileNotFoundException;
@RestController
@RequestMapping("/file")
public class FileController {
@Autowired
private MinIOHelper minIOHelper;
@PostMapping("/upload")
@ResponseBody
public String upload(MultipartFile file, HttpServletRequest request) {
try {
String filePath = minIOHelper.uploadFile(file, null, null);
return filePath;
} catch (FileNotFoundException e) {
throw new CustomException("FILE_NOT_FOUND", "文件未找到");
}
}
}
FAQ
io.minio.S3Base.(S3Base.java:105)
An attempt was made to call a method that does not exist. The attempt was made from the following location:
io.minio.S3Base.<clinit>(S3Base.java:105)
The following method did not exist:
okhttp3.RequestBody.create([BLokhttp3/MediaType;)Lokhttp3/RequestBody;
The method's class, okhttp3.RequestBody, is available from the following locations:
jar:file:/D:/repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar!/okhttp3/RequestBody.class
The class hierarchy was loaded from the following locations:
okhttp3.RequestBody: file:/D:/repository/com/squareup/okhttp3/okhttp/3.14.9/okhttp-3.14.9.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of okhttp3.RequestBody
问题原因
Spring boot 和minio 依赖冲突产生的原因是因为spring boot 的okhttp 和minio 的okhttp冲突
解决办法
降低minio版本:8.3.0 —> 8.2.1
边栏推荐
- Placement Rules usage documentation
- The service already exists!解决办法
- Leetcode 118. 杨辉三角
- 【HMS core】【FAQ】push kit、分析服务、视频编辑服务典型问题合集3
- [HMS core] [FAQ] Collection of typical problems of push kit, AR Engine, advertising service, scanning service 2
- 【AGC】Open Test Example
- 二、判断 & 循环
- [flutter]什么是MaterialApp和Material design
- 华为ADS获取转化跟踪参数报错:getInstallReferrer IOException: getInstallReferrer not found installreferrer
- 【HMS core】【Media】【视频编辑服务】 在线素材无法展示,一直Loading状态或是网络异常
猜你喜欢

Google engineer "code completion" tool; "Transformers NLP" accompanying book code; FastAPI development template; PyTorch model acceleration tool; cutting-edge papers | ShowMeAI News Daily
![[flutter] What is MaterialApp and Material design](/img/72/d0845467b33b2291f47e7f54171088.jpg)
[flutter] What is MaterialApp and Material design

一文读懂Elephant Swap,为何为ePLATO带来如此高的溢价?

SMI 与 Gateway API 的 GAMMA 倡议意味着什么?

yarn的安装及使用教程

arcpy使用教程

hcip--ospf综合实验

3D激光SLAM:LeGO-LOAM论文解读---激光雷达里程计与建图

rscsa笔记八

武汉星起航:海外仓基础建设成为跨境电商企业的一大出海利器
随机推荐
解析字符串拼接的两种情况
TiUP terms and core concepts
[flutter]什么是MaterialApp和Material design
三维重建方法汇总
新人学习小熊派网络应用开发
php how to query string occurrence position
Google engineer "code completion" tool; "Transformers NLP" accompanying book code; FastAPI development template; PyTorch model acceleration tool; cutting-edge papers | ShowMeAI News Daily
Shell脚本的概念
数组元素逆置
为什么数据需要序列化
Database - SQL
FME realizes the method of converting CAD with attribute to SHP data
Why is there no data reported when the application is connected to Huawei Analytics in the application debugging mode?
动态规划 --- 状态压缩DP 详细解释
【HMS core】【FAQ】push kit, WisePlay DRM, Location Kit, Health Kit, 3D Modeling Kit, SignPal Kit Typical Questions Collection 4
绕开驱动层检测的无痕注入
新技术要去做新价值
Goland 开启文件保存自动进行格式化
When the vite multi-page application refreshes the page, it will not be in the current route and will return to the root route
MySql 和 PostgreSQL 数据库 根据一张表update另一张表数据