搭建高性能分布式存储-minio
文章目录
- 搭建高性能分布式存储-minio
- Docker搭建minio(单机部署+纠删码模式)⭐
- 创建minio的bucket(桶)⭐
- SpringBoot+minio项目实战 ⭐
- 1:导入minio的maven依赖
- 2:编写MinioProperties.class
- 3:application.yml:
- 4:MinioConfig.class配置类
- 5:ResponseResult(统一响应结果)
- 6:ResponseType(响应类型枚举类)
- 7:UploadController.class(上传接口)
- 8:上传service接口
- 9:上传service接口实现类:
搭建高性能分布式存储-minio
Docker搭建minio(单机部署+纠删码模式)⭐
- 1:使用minio Docker镜像,在在单机中使用EC纠删码模式部署,8块盘中启动minio服务:
- 注意:MINIO_ROOT_PASSWORD初始化默认密码长度必须要达到8位。
docker run --name minio -d \-p 9000:9000 \-p 50000:50000 \-v /mnt/minio/data1:/data1 \-v /mnt/minio/data2:/data2 \-v /mnt/minio/data3:/data3 \-v /mnt/minio/data4:/data4 \-v /mnt/minio/data5:/data5 \-v /mnt/minio/data6:/data6 \-v /mnt/minio/data7:/data7 \-v /mnt/minio/data8:/data8\-e MINIO_ROOT_USER="root" \-e MINIO_ROOT_PASSWORD="12345678" \minio/minio:latest server /data{1...8} --console-address ":50000"
- 2:访问minio控制台:(http://服务器ip:50000/)
创建minio的bucket(桶)⭐







SpringBoot+minio项目实战 ⭐
1:导入minio的maven依赖
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.3</version>
</dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version>
</dependency>
2:编写MinioProperties.class
package com.boot.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;/*** 高性能分布式存储-minio属性类** @author youzhengjie* @date 2022/10/28 00:22:48*/
@Component
@Data
@ConfigurationProperties(prefix = "minio")
@EnableConfigurationProperties({MinioProperties.class
})
public class MinioProperties {/*** minio的通信端点(url),和控制台端点不一样*/private String endpoint;/*** 说白了就是minio的帐号*/private String accessKey;/*** 说白了就是minio的密码*/private String secretKey;/*** 指定操作哪一个桶*/private String bucketName;
}
3:application.yml:
- 注意:记得把下面的配置属性修改成你自己的!
minio:endpoint: http://192.168.184.123:9000access-key: rootsecret-key: 12345678bucket-name: security-jwt2-bucket
4:MinioConfig.class配置类
- 作用是将MinioClient交给Spring管理,方便后续直接@AutoWired注入即可使用)
package com.boot.config;import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** minio配置类** @author youzhengjie* @date 2022/10/28 00:30:31*/
@Configuration
public class MinioConfig {@Autowiredprivate MinioProperties minioProperties;/*** minio-client bean** @return {@link MinioClient}*/@Beanpublic MinioClient minioClient(){return MinioClient.builder()//配置minio的通信端点(url),和控制台端点不一样.endpoint(minioProperties.getEndpoint())//配置minio的帐号密码.credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey()).build();}}
5:ResponseResult(统一响应结果)
package com.boot.data;import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 统一响应结果*/
@JsonInclude(JsonInclude.Include.NON_NULL) //为null的字段不进行序列化
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResponseResult<T> {/*** 响应状态码*/private Integer code;/*** 响应状态码对应的信息提示*/private String msg;/*** 返回给前端的数据*/private T data;public ResponseResult(Integer code, String msg) {this.code = code;this.msg = msg;}public ResponseResult(Integer code, T data) {this.code = code;this.data = data;}}
6:ResponseType(响应类型枚举类)
package com.boot.enums;/*** 响应类型枚举类* @author youzhengjie* @date 2022-09-22 22:47:21*/
public enum ResponseType {/*** 文件操作状态*/IMAGE_UPLOAD_SUCCESS(901,"图片上传成功"),IMAGE_UPLOAD_ERROR(902,"图片上传失败"),FILE_FORMAT_UNSUPPORT(903,"不支持该文件格式,上传失败"),FILE_DELETE_SUCCESS(904,"文件删除成功"),FILE_DELETE_ERROR(905,"文件删除失败"),;private int code;private String message;ResponseType(int code, String message) {this.code = code;this.message = message;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}
7:UploadController.class(上传接口)
@RestController
@Api("上传接口")
@RequestMapping(path = "/upload")
@Slf4j
public class UploadController {@Autowired@Qualifier("minioUploadServiceImpl") //指定spring注入的实现类private OssUploadService ossUploadService;/*** 上传头像** @param avatarFile 头像文件(名字一定要和el-upload的:name属性一致)* @return {@link ResponseResult}*/@OperationLog("上传头像")@PostMapping(path = "/avatar")@ApiOperation("上传头像")public ResponseResult uploadAvatar(MultipartFile avatarFile){ResponseResult result = ossUploadService.imageUpload(avatarFile);return result;}/*** 文件删除** @param fileFullName 文件名* @return {@link ResponseResult}*/@OperationLog("文件删除")@DeleteMapping(path = "/fileDelete")@ApiOperation("文件删除")public ResponseResult fileDelete(@RequestParam("fileFullName") String fileFullName){return ossUploadService.fileDelete(fileFullName);}/*** 文件下载** @param fileName 文件名称* @param response 响应*/@GetMapping(path = "/fileDownload")@ApiOperation("文件下载")public void fileDownload(@RequestParam("fileName") String fileName, HttpServletResponse response){ossUploadService.fileDownload(fileName,response);}
}
8:上传service接口
package com.boot.service;import com.boot.data.ResponseResult;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;/*** oss上传service接口* @author youzhengjie* @date 2022-10-06 23:13:28*/
public interface OssUploadService {/*** oss图片上传* @param imageFile* @return 上传结果*/ResponseResult imageUpload(MultipartFile imageFile);/*** oss文件删除* @param fileFullName 文件全名,** @return 删除结果*/ResponseResult fileDelete(String fileFullName);/*** 文件下载** @param fileName 文件名称* @param response 响应*/default void fileDownload(String fileName, HttpServletResponse response){throw new UnsupportedOperationException("该实现类暂不支持文件下载操作,请切换到其他实现类!");}}
9:上传service接口实现类:
package com.boot.service.impl;import com.boot.config.MinioProperties;
import com.boot.data.ResponseResult;
import com.boot.enums.ResponseType;
import com.boot.service.OssUploadService;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;/*** minio上传服务service impl** @author youzhengjie* @date 2022/10/28 13:59:35*/
@Service("minioUploadServiceImpl")
@Slf4j
public class MinioUploadServiceImpl implements OssUploadService {@Autowiredprivate MinioProperties minioProperties;/*** 注入MinioClient,用于操作minio*/@Autowiredprivate MinioClient minioClient;/*** 检查文件是否是图片类型* @param originalFilename* @return true代表是图片,false则不是图片*/private boolean isImage(String originalFilename){//将文件名全部变小写String lowerOriginalFilename = originalFilename.toLowerCase();return lowerOriginalFilename.endsWith(".jpg") ||lowerOriginalFilename.endsWith(".png") ||lowerOriginalFilename.endsWith(".jpeg");}/*** minio图片上传** @param imageFile 图像文件* @return {@link ResponseResult}*/@Overridepublic ResponseResult imageUpload(MultipartFile imageFile) {//封装响应结果ResponseResult<Object> result = new ResponseResult<>();try {//获取上传前的文件原名String oldFileName = imageFile.getOriginalFilename();//如果不是图片则直接返回if(!isImage(oldFileName)){result.setCode(ResponseType.FILE_FORMAT_UNSUPPORT.getCode());result.setMsg(ResponseType.FILE_FORMAT_UNSUPPORT.getMessage());return result;}//以日期作为目录,每一天的图片都会放到不同的目录下,方便管理String fileDir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd/"));//UUID文件名String uuidFileName = UUID.randomUUID().toString().replaceAll("-", "");//获取文件后缀名 .jpgString fileSuffix= oldFileName.substring(oldFileName.lastIndexOf("."));//上传到minio中的新的图片文件名String newFileName = new StringBuilder().append(fileDir).append(uuidFileName).append(fileSuffix).toString();//获取文件流InputStream inputStream = imageFile.getInputStream();//获取文件大小long size = imageFile.getSize();//获取内容类型String contentType = imageFile.getContentType();//构建文件上传所需要的东西(PutObjectArgs)PutObjectArgs putObjectArgs = PutObjectArgs.builder().bucket(minioProperties.getBucketName()).object(newFileName).stream(inputStream, size, -1).contentType(contentType).build();//开始进行minio文件上传minioClient.putObject(putObjectArgs);//获取该上传到minio的文件的url(使外网可以访问)String fileUrl=minioProperties.getEndpoint()+"/"+minioProperties.getBucketName()+"/"+newFileName;result.setCode(ResponseType.IMAGE_UPLOAD_SUCCESS.getCode());result.setMsg(ResponseType.IMAGE_UPLOAD_SUCCESS.getMessage());result.setData(fileUrl);return result;}catch (Exception e){e.printStackTrace();result.setCode(ResponseType.IMAGE_UPLOAD_ERROR.getCode());result.setMsg(ResponseType.IMAGE_UPLOAD_ERROR.getMessage());return result;}}/*** minio文件删除** @param fileFullName 文件全名 。格式例如:2022/10/28/4f74aa358a4548d4860c110ebec3831f.jpg* @return {@link ResponseResult}*/@Overridepublic ResponseResult fileDelete(String fileFullName) {//封装响应结果ResponseResult<Object> result = new ResponseResult<>();try {RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(minioProperties.getBucketName()).object(fileFullName).build();minioClient.removeObject(removeObjectArgs);result.setCode(ResponseType.FILE_DELETE_SUCCESS.getCode());result.setMsg(ResponseType.FILE_DELETE_SUCCESS.getMessage());return result;}catch (Exception e){e.printStackTrace();result.setCode(ResponseType.FILE_DELETE_ERROR.getCode());result.setMsg(ResponseType.FILE_DELETE_ERROR.getMessage());return result;}}/*** minio文件下载。** @param fileName 文件名称 。格式例如:2022/10/28/4f74aa358a4548d4860c110ebec3831f.jpg* @param response 响应*/@Overridepublic void fileDownload(String fileName, HttpServletResponse response) {try {// 获取对象信息StatObjectArgs statObjectArgs = StatObjectArgs.builder().bucket(minioProperties.getBucketName()).object(fileName).build();StatObjectResponse statObject = minioClient.statObject(statObjectArgs);/*** 描述: content-type 指示响应内容的格式* content-disposition 指示如何处理响应内容。* 一般有两种方式:* inline:直接在页面显示-预览* attachment:以附件形式下载-下载*/response.setContentType(statObject.contentType());
// response.setHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(fileName, "UTF-8"));response.setHeader("Content-Disposition", "attachment; filename=" +URLEncoder.encode(fileName, "UTF-8"));InputStream inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minioProperties.getBucketName()).object(fileName).build());IOUtils.copy(inputStream,response.getOutputStream());}catch (Exception e){throw new RuntimeException("文件下载失败");}}
}
相关文章:
搭建高性能分布式存储-minio
文章目录 搭建高性能分布式存储-minioDocker搭建minio(单机部署纠删码模式)⭐创建minio的bucket(桶)⭐SpringBootminio项目实战 ⭐1:导入minio的maven依赖2:编写MinioProperties.class3:applica…...
leetCode 137. 只出现一次的数字 II(拓展篇) + 模5加法器 + 真值表(数字电路)
leetCode 137. 只出现一次的数字 II 题解可看我的往期文章 leetCode 137. 只出现一次的数字 II 位运算 模3加法器 真值表(数字电路) 有限状态机-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/134138112?spm1001.2014.3001.5501…...
docker导致root空间满进入不了系统解决方案
由于docker建立镜像会产生很多缓存文件,最终导致root目录满,进入不了系统 df -h docker默认路径是在/var/lib/docker下 可以通过命令查看docker占用空间 docker system df 如果占用空间太大 可用以下命令清理 $ docker image prune -h Flag shorth…...
uni-app遮罩遮住小程序tabbar
uni-app遮罩遮住小程序tabbar 1、用uni-app自带的方法显示隐藏 //通过弹窗显隐控制导航栏的显示和隐藏 const popupChange e >{if(e.show){//隐藏tabbaruni.hideTabBar()}else{//显示tabbaruni.showTabBar()}state.searchIcon e.show } //通过弹窗显隐控制导航栏的显示和…...
Flink on yarn 加载失败plugins失效问题解决
Flink on yarn 加载失败plugins失效问题解决 flink版本:1.13.6 1. 问题 flink 任务运行在yarn集群,plugins加载失效,导致通过扩展资源获取任务参数失效 2. 问题定位 yarn容器的jar包及插件信息,jar包是正常上传 源码定位 加载plugins入口,TaskMana…...
显卡服务器的特点和优势在哪里
随着科技的发展以及人们对于计算机性能的需求提高,显卡服务器是主要使用图形处理器进行计算和运算,拥有更加强大的计算能力,今天小编就来给大家讲一讲显卡服务器的特点和优势是什么! 1.高可靠性:显卡服务器采用高品质的…...
c++设计模式二:原型模式
使用场景:当需要构建多个相同的类对象时,而且该类对象结构较为复杂,如果每个都重新组织构建会很麻烦。 其实,就是写一个拷贝构造函数,或者写一个拷贝每个成员变量的clone()方法。 举例说明:比如一个相亲网站…...
【Qt控件之QMessageBox】详解
Qt控件之QMessageBox 描述基于属性的API富文本和文本格式属性严重程度以及图标和Pixmap属性静态函数API 高级用法默认按钮和退出按钮示例使用场景 描述 QMessageBox类提供了一个模态对话框,用于通知用户或向用户提问并接收答案。 消息框显示一个主要文本以提醒用户…...
SSH安全登录远程主机
SSH服务器简介 SSH即Security SHell的意思,它可以将连线的封包进行加密技术,之后进行传输,因此相当的安全。 SSH是一种协议标准,其目的是实现安全远程登录以及其它安全网络服务。 SSH协定,在预设的状态下,…...
揭秘!产品经理提升效率的秘密武器:10款AI生成PPT工具
AI的爆炸式增长表现令人惊艳,现有的各类AI工具正在重塑各行各业,不同程度地提高人们的工作效率,并有望创造新的职业机会。但是,面对市面上数量众多的AI工具,且每周都会蹦出新的产品,即便是以好奇心富称的产…...
Oracle修改带数据的字段类型
insert into TNW_FUND_SELORG(TFDINFOID,TSOINFOID) select TFD_INFO_ID,TSO_INFO_ID from TFD_SEL_FUNDLINK_TO_OLDFUNDWEB_DB /*修改原字段名*/ ALTER TABLE 表名 RENAME COLUMN 字段名 TO 字段名1; /*添加一个和原字段同名的字段*/ ALTER TABLE 表名 ADD 字段名 VARCHAR…...
WebService接口方式和Restful接口这两者有什么区别和相同点
WebService和RESTful接口都是用于在网络上进行通信和数据交换的技术,但它们在设计和使用上有一些重要的区别和相似之处。 相同点: 基于HTTP协议:无论是WebService还是RESTful接口,它们都是通过HTTP协议进行通信的。 支持多种数据…...
jenkins自动化操作步骤(gitblit)
1、登陆地址: http://xxxxxxxxx.org:xxxx/ admin/xxxx 2、创建任务 选择构建一个maven项目 3、配置 最多只保留一天一个任务 选择git仓库和账号密码 选择代码对应分支 build项: 1)使用父项目的pom文件:k56-boot/pom.xml 2&…...
centos中mongodb设置服务自启动并 允许远程IP访问
安装mongodb参考 注意的是配置文件需要把journal设置为true 制作为系统服务 创建MongoDB服务文件。运行以下命令创建服务文件/etc/systemd/system/mongod.service: vi /etc/systemd/system/mongod.service [Unit] DescriptionMongoDB Database Server Documenta…...
实时定位和配送追踪:开发万岳同城外卖APP的关键技术特性
随着生活节奏的不断加快,外卖服务已经成为许多人日常生活中不可或缺的一部分。无论是工作日的午餐,还是周末的家庭聚会,外卖APP已经成为满足各种美食需求的首选方式。然而,同城外卖APP的成功不仅仅取决于美味的食物选择࿰…...
数据库强化(3.存储过程)
1.什么是存储过程? 存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。MySQL 5.0 版本开始支持存储过程。 它是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中&a…...
雅思小作文笔记
mostly from Simon’s methods and techniques remember the task is describe what you see, not give an opinion. Just write a report.no conclusion, just a summary(the overview) Question type 小作文的题目类型大致如上 Simon所述,在描述数字的时候&…...
Java List Set Map
一、List 1.1 ArrayList 1.2 LinkedList 二、Set 2.1 HashSet 2.2 TreeSet 2.3 LinkedHashSet 三、Map 3.1 HashMap 3.2 TreeMap 3.3 LinkedHashMap 四、对比 类型底层结构重复null值场景备注查询删除新增ListArrayList动态数组可允许快速随机访问元素0(1)0(n)尾部增加0&a…...
【数据结构】数组和字符串(十三):链式字符串的基本操作(串长统计、查找、复制、插入、删除、串拼接)
文章目录 4.3 字符串4.3.1 字符串的定义与存储4.3.2 字符串的基本操作(链式存储)1. 结构体2. 初始化3. 判空4. 串尾添加5. 打印6. 串长统计7. 查找8. 复制9. 插入10. 删除11. 串拼接12. 销毁13. 主函数14. 代码整合 4.3 字符串 字符串(String)是由零个或…...
Python3 获取当前服务器公网 IP 地址
有同学问我如何使用 Python 获取服务器公网的 IP 地址呢?我测试几个发现,方法有很多,好用的就发现一种,即直接使用 Python 自带的 socket 包。 代码示例: # 获取主机 IP dgram socket.socket(socket.AF_INET, socke…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
ArcPy扩展模块的使用(3)
管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如,可以更新、修复或替换图层数据源,修改图层的符号系统,甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...
