搭建高性能分布式存储-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…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
