Minio安装及整合SpringBoot

一. MinIO概述

官网地址:https://minio.org.cn

MinIO是一款基于Apache License v2.0开源协议的分布式文件系统(或者叫对象存储服务),可以做为云存储的解决方案用来保存海量的图片、视频、文档等。由于采用Golang实现,服务端可以工作在Windows、Linux、 OS X和FreeBSD上。配置简单,基本是复制可执行程序,单行命令就可以运行起来。

MinIO兼容亚马逊S3(Simple Storage Service,简单存储服务)云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而且每个对象文件可以是任意大小,从几kb到最大5T不等。

 MinIO特点:

1. 高性能:作为高性能对象存储,在标准硬件条件下它能达到55GB/s的读、35GB/s的写速率;
2. 可扩容:不同MinIO集群可以组成联邦,并形成一个全局的命名空间,并跨越多个数据中心;
3. SDK支持: 基于Minio轻量的特点,它得到类似Java、Python或Go等语言的sdk支持;
4. 支持纠删码:MinIO使用纠删码、Checksum来防止硬件错误和静默数据污染。在最高冗余度配  置下,即使丢失1/2的磁盘也能恢复数据;

MinIO基本概念:

  • bucket(桶) :类似文件系统的目录(文件夹);
  • Object : 类似文件系统的文件;
  • Keys :类似文件名;
  • MINIO_ACCESS_KEY:访问key,类似账号;
  • MINIO_SECRET_KEY:秘钥,类似密码。
二. Dokcer安装Minio
2.1 创建文件夹

在home/docker/minio文件夹下创建两个文件夹,分别是data、config,用于挂载容器中的数据卷。

mkdir home/docker/minio/data
mkdir home/docker/minio/config
2.1 拉取镜像
docker pull minio/minio
2.3 启动容器
docker run -p 9000:9000 -p 9001:9001\--name minio \-d --restart=always \-e "MINIO_ROOT_USER=minio" \-e "MINIO_ROOT_PASSWORD=minio123" \-v /home/docker/minio/data:/data \
-v /home/docker/minio/config \minio/minio server \/data --console-address ":9001" -address ":9000"

参数说明

  • -p:MinIO 服务会暴露 9000 端口作为API端口,9001 端口为可视化管理页面端口
  • -v :挂载数据卷,将 minio 容器内存储的数据、配置文件映射到宿主机
  • -e MINIO_ROOT_USER:设置 root 用户名
  • -e MINIO_ROOT_PASSWORD:设置 root 的密码,长度至少 8 位
  • --console-address:指定可视化界面端口
  • -address:指定服务端口

记得开放安全组!

2.4 查看日志
docker logs minio容器id

通过以上命令查看 minio 日志,会输出以下内容:

我们可以通过日志中的Console地址来访问可视化界面。

三.访问Minio

登录成功后,可以创建桶

 此时在桶列表会会出现刚刚创建的桶,点击Manage,设置桶的访问策略,修改为 Public 公共策略,这样 minio 中的文件才能被外界访问

 并可以直接在桶中上传文件。

四. 整合Springboot完成文件上传
4.1创建springboot工程
4.2 导入相关依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- 必须要导入OKhttp的依赖 --><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.8.1</version></dependency><!-- https://mvnrepository.com/artifact/io.minio/minio --><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.7</version></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
</dependencies>
4.3 yaml中配置 Minio

在 yaml 中新增以下配置:

minio:accessKey: minio # 访问KeysecretKey: minio123 # 密钥bucket: test endpoint: http://xxx.x.x.x:9000 # ip:api端口readPath: http://xxx.x.x.x:9000 # ip:api端口servlet:multipart:# 单个上传文件的最大值是200mbmax-file-size: 200MB# 单次请求的最大值max-request-size: 200MB
4.4 编写 MinIO属性配置类
@Data
@Component
@ConfigurationProperties(prefix = "minio")  //自动注入属性前缀为minio的配置
public class MinIOConfigProperties implements Serializable {private String accessKey; // 访问keyprivate String secretKey; // 秘钥private String bucket;    // 桶private String endpoint;  // 地域节点private String readPath;  // 读取路径
}
4.5 编写MinIO配置类,注册MinioClient客户端Bean实例
@Configuration
public class MinIOConfig {@Autowiredprivate MinIOConfigProperties minIOConfigProperties;// 注册MinIO实例@Beanpublic MinioClient buildMinioClient(){return MinioClient.builder().credentials(minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey()).endpoint(minIOConfigProperties.getEndpoint()).build();}
}
4.6 编写操作minio相关业务接口
public interface FileStorageService {/*** 上传图片文件** @param prefix      文件前缀* @param filename    文件名* @param inputStream 文件流* @return 文件全路径*/public String uploadImgFile(String prefix, String filename, InputStream inputStream);/*** 上传html文件** @param prefix      文件前缀* @param filename    文件名* @param inputStream 文件流* @return 文件全路径*/public String uploadHtmlFile(String prefix, String filename, InputStream inputStream);/*** 删除文件** @param pathUrl 文件全路径*/public void delete(String pathUrl);/*** 下载文件** @param pathUrl 文件全路径* @return*/public byte[] downLoadFile(String pathUrl);}

业务接口实现类:

@Service
public class MinIOFileStorageService implements FileStorageService {@AutowiredMinioClient minioClient;@AutowiredMinIOConfigProperties minIOConfigProperties;final static String separator = "/"; //文件夹分隔符/*** 构建文件的绝对路径** @param dirPath  文件路径* @param filename 文件名  yyyy/mm/dd/file.jpg* @return /test*/public String builderFilePath(String dirPath, String filename) {StringBuilder stringBuilder = new StringBuilder(50);if (!StringUtils.isEmpty(dirPath)) {stringBuilder.append(dirPath).append(separator);}SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");String todayStr = sdf.format(new Date());stringBuilder.append(todayStr).append(separator);stringBuilder.append(filename);return stringBuilder.toString();}/*** 上传图片文件** @param prefix      文件前缀* @param filename    文件名* @param inputStream 文件流* @return 文件全路径*/@Overridepublic String uploadImgFile(String prefix, String filename, InputStream inputStream) {String filePath = builderFilePath(prefix, filename);try {PutObjectArgs putObjectArgs = PutObjectArgs.builder().object(filePath).contentType("image/jpg").bucket(minIOConfigProperties.getBucket()).stream(inputStream, inputStream.available(), -1).build();minioClient.putObject(putObjectArgs);StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());urlPath.append(separator + minIOConfigProperties.getBucket());urlPath.append(separator);urlPath.append(filePath);return urlPath.toString();} catch (Exception ex) {throw new RuntimeException("上传文件失败");}}/*** 上传html文件** @param prefix      文件前缀* @param filename    文件名* @param inputStream 文件流* @return 文件全路径*/@Overridepublic String uploadHtmlFile(String prefix, String filename, InputStream inputStream) {String filePath = builderFilePath(prefix, filename);try {PutObjectArgs putObjectArgs = PutObjectArgs.builder().object(filePath) //文件名.contentType("text/html")//文件类型.bucket(minIOConfigProperties.getBucket())//桶名称与minio创建的桶一致.stream(inputStream, inputStream.available(), -1)//文件流.build();minioClient.putObject(putObjectArgs);StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());urlPath.append(separator + minIOConfigProperties.getBucket());urlPath.append(separator);urlPath.append(filePath);return urlPath.toString(); //文件全路径} catch (Exception ex) {ex.printStackTrace();throw new RuntimeException("上传文件失败");}}/*** 删除文件** @param pathUrl 文件全路径*/@Overridepublic void delete(String pathUrl) {String key = pathUrl.replace(minIOConfigProperties.getEndpoint() + "/", "");int index = key.indexOf(separator);String bucket = key.substring(0, index);String filePath = key.substring(index + 1);// 删除ObjectsRemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();try {minioClient.removeObject(removeObjectArgs);} catch (Exception e) {e.printStackTrace();}}/*** 下载文件** @param pathUrl 文件全路径* @return 文件流*/@Overridepublic byte[] downLoadFile(String pathUrl) {String key = pathUrl.replace(minIOConfigProperties.getEndpoint() + "/", "");int index = key.indexOf(separator);String bucket = key.substring(0, index);String filePath = key.substring(index + 1);InputStream inputStream = null;try {inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minIOConfigProperties.getBucket()).object(filePath).build());} catch (Exception e) {e.printStackTrace();}//字节数组输出流ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buff = new byte[100];int rc = 0;while (true) {try {if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break;} catch (IOException e) {e.printStackTrace();}byteArrayOutputStream.write(buff, 0, rc);}return byteArrayOutputStream.toByteArray();}}
4.7 编写controller进行测试
@RestController
@RequestMapping("/minio")
public class MinioController {@Autowiredprivate FileStorageService fileStorageService;/*** 上传图片到minio** @param file* @return*/@PostMapping("/upload")public void uploadFile(MultipartFile file) throws IOException {try {// 获取文件名称String fileName = file.getOriginalFilename();/*解决多次上传同名文件覆盖问题*/// 在文件名称里面添加随机唯一的值String uuid = UUID.randomUUID().toString().replaceAll("-", "");fileName = uuid + fileName;// 获取文件输入流InputStream is = file.getInputStream();String imgUrl = fileStorageService.uploadImgFile("img", fileName, is);return "上传成功!imgUrl:"+imgUrl;} catch (IOException e) {e.printStackTrace();return "上传失败";}}}
4.8 启动项目,测试

查看 Minio 可视化界面图片是否上传成功

可通过ip+图片路径直接访问。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/622345.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

细说JavaScript语句详解

一、顺序结构 二、表达式语句 三、声明语句 四、条件语句 1、if语句 2、if…else语句 3、else if语句 4、switch语句 五、循环语句 1、while循环 2、do… while循环 3、for循环 4、for…in循环 六、跳出语句 1、label语句 2、break语句 3、continue语句

对闭包的理解

概念&#xff1a; 一个函数对周围状态的引用捆绑在一起&#xff0c;闭包让开发者可以从内部函数访问外部 函数的作用域 简单理解&#xff1a;闭包 内层函数 外层函数的变量 一个函数对周围状态的引用捆绑在一起&#xff0c;闭包让开发者可以从内部函数访问外部 函数的作…

数据结构——顺序二叉树——堆

1.树的相关概念 在介绍二叉树之前&#xff0c;我们首先要明确树是什么。 树用我们的通常认识来判断应该是一种植物&#xff0c;从根向上生长&#xff0c;分出许多的树枝并长出叶子。对于数据结构中的树而言&#xff0c;其结构也正是从树的特征中剥离出来的。树结构是一种非线性…

第二百六十六回

文章目录 1. 概念介绍2. 分析与解决2.1 分析问题2.2 解决方案 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何修改CircleAvatar的大小"相关的内容&#xff0c;本章回中将介绍如何修改StatusBar中文字的颜色.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1.…

深入理解JVM虚拟机第三十八篇:JVM中OOM的说明和举例

😉😉 欢迎加入我们的学习交流群呀! ✅✅1:这是孙哥suns给大家的福利! ✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring、Security、Docker、Grpc、消息中间件、Rpc、SpringCloud等等很多应用和源码级别高质量视频和笔记资料,你想学的我们这里都有! 🥭🥭3:…

【笔记】书生·浦语大模型实战营——第四课(XTuner 大模型单卡低成本微调实战)

【参考&#xff1a;tutorial/xtuner/README.md at main InternLM/tutorial】 【参考&#xff1a;(4)XTuner 大模型单卡低成本微调实战_哔哩哔哩_bilibili-【OpenMMLab】】 总结 学到了 linux系统中 tmux 的使用 了解了 XTuner 大模型微调框架的使用 pth格式参数转Hugging …

C++学习笔记——SLT六大组件及头文件

目录 一、C中STL&#xff08;Standard Template Library&#xff09; 二、 Gun源代码开发精神 三、 实现版本 四、GNU C库的头文件分布 bits目录 ext目录 backward目录 iostream目录 stdexcept目录 string目录 上一篇文章&#xff1a; C标准模板库&#xff08;STL&am…

原生js实现拖拽效果

<!DOCTYPE html> <html> <head> <style> #mydiv { width: 200px; height: 200px; background-color: red; position: absolute; cursor: move; } </style> | </head> <body> <div id"mydiv">拖拽我…

什么是信噪比

大家好&#xff0c;今天给大家介绍什么是信噪比&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 “信噪比”是电子技术中经常用到的一个词组&#xff0c;知道它的确切含义有一定意…

vivado18.3和modelsim关联

版本关系 首先明确Modelsim与Vivado的联合仿真需要版本号相匹配&#xff0c;Xilinx官方文档UG973中给出了所有版本的Vivado兼容Modelsim的版本情况 Vivado版本号Modelsim版本号Vivado Design Suite 2022.2Mentor Graphics ModelSim DE (2022.2)Vivado Design Suite 2022.1Men…

【前端性能优化】如何取消http请求

文章目录 需要取消http请求的3种经典场景原生XMLHttpRequest取消http请求fetch取消http请求axios取消http请求哪些情况需要取消HTTP请求取消http请求能带来哪些性能提升 需要取消http请求的3种经典场景 场景一&#xff1a;有一个实时搜索功能&#xff0c;每当用户输入内容改变的…

python爬虫小练习——爬取豆瓣电影top250

爬取豆瓣电影top250 需求分析 将爬取的数据导入到表格中&#xff0c;方便人为查看。 实现方法 三大功能 1&#xff0c;下载所有网页内容。 2&#xff0c;处理网页中的内容提取自己想要的数据 3&#xff0c;导入到表格中 分析网站结构需要提取的内容 代码 import requests…

【昕宝爸爸小模块】线程的几种状态,状态之间怎样流转

➡️博客首页 https://blog.csdn.net/Java_Yangxiaoyuan 欢迎优秀的你&#x1f44d;点赞、&#x1f5c2;️收藏、加❤️关注哦。 本文章CSDN首发&#xff0c;欢迎转载&#xff0c;要注明出处哦&#xff01; 先感谢优秀的你能认真的看完本文&…

vue中动态给不同表单赋值

这里的业务是通过关联的 id 发送不同的请求获取表单的数据&#xff0c;然后回显到页面中&#xff0c;整个的页面是由多个表单拼接起来的 点击下一步的时候&#xff0c;获取下一个表单的内容。 // 查询getForm(index) {switch (index) {case 0:this.getFromInfo("inputFor…

图鸟Vue3版本部署

无法将“pnpm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。 分析原因 这个错误信息表明在 VS Code 终端中尝试运行 pnpm install&#xff0c;但系统无法识别 pnpm 命令。这通常表示 pnpm 这个工具没有被正确安装&#xff0c;或者它的可执行文件所在的路径没有被正确…

故障诊断全家桶,看这一篇就够了,精品力荐!

本期推出故障诊断全家桶&#xff0c;包含传统的分析时频诊断方法&#xff0c;依靠数据分解方法的诊断方法&#xff0c;依靠机器学习的诊断方法。还包含了6种适应度函数随意切换的VMD优化方法&#xff0c;16种数据分解方法&#xff0c;包络谱&#xff0c;包络熵等代码。以及作者…

剪映国际版,免费无限制使用

随着抖音的爆火短视频的崛起&#xff0c;相信每一个人都感受到了短视频快节奏下的生活洪流。 现如今每个人都能成为自己生活的记录者&#xff0c;每一个人都有掌握着剪辑的基本技能。而剪映就是很多人都会使用的剪辑软件。 相对于PR、AE等剪辑软件来说&#xff0c;作为一款国…

【金猿CIO展】步长制药信息化管理与建设中心总经理束炼:IT部门既要懂技术,也要懂业务...

‍ 束炼 本文由步长制药信息化管理与建设中心总经理束炼撰写并投递参与“数据猿年度金猿策划活动——2023大数据产业年度优秀CIO榜单及奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 随着数字化转型的浪潮席卷各行各业&#xff0c;中国数字经济已进入快速发展阶…

Mybatis 常用条件语句,大于小于、if、for、模糊搜索、case when、choose

大于小于 方法1&#xff1a; > 大于 &#xff0c; < 小于 <if test"startTime ! null ">and a.create_time > #{startTime} </if> <if test"endTime ! null ">and a.create_time < #{endTime} </if> 方法2(建议写这…

PLECS如何下载第三方库并导入MOSFET 的xml文件,xml库路径添加方法及相关问题

1. 首先xml库的下载&#xff0c;PLECS提供了一个跳转的链接。 https://www.plexim.com/download/thermal_models 2. 下载一个库&#xff08;以最后一个Wolfspeed为例&#xff0c;属于CREE的SiC MOSFET&#xff09; 下载这个就行&#xff0c;都包含了。不信自己可以试试再下载…