0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用docker搭建minio服务

倩倩 来源:CSDN 作者:CSDN 2022-09-23 11:08 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群


什么是minio

引用官网:

MinIO是根据GNU Affero通用公共许可证v3.0发布的高性能对象存储。它与Amazon S3云存储服务兼容。使用MinIO构建用于机器学习,分析和应用程序数据工作负载的高性能基础架构。

官网地址:

https://min.io/

文档地址:

https://docs.min.io/

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

一. 使用docker 搭建minio 服务。

GNU / Linux和macOS

dockerrun-p9000:9000
--nameminio1
-v/mnt/data:/data
-e"MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE"
-e"MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
minio/minioserver/data

windows

dockerrun-p9000:9000
--nameminio1
-vD:data:/data
-e"MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE"
-e"MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
minio/minioserver/data
  • MINIO_ROOT_USER:为用户key
  • MINIO_ROOT_PASSWORD:为用户密钥

以上搭建的都是单机版的。想要了解分布式 的方式请查看官网文档。

a62be472-3ae9-11ed-9e49-dac502259ad0.png

这就是在win的docker上运行的。

当启动后在浏览器访问http://localhost:9000就可以访问minio的图形化界面了,如图所示:

a65eb08c-3ae9-11ed-9e49-dac502259ad0.pnga6875ba4-3ae9-11ed-9e49-dac502259ad0.png

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

二. 下面开始搭建springboot 环境

初始化一个springboot项目大家都会,这里不多做介绍。

主要是介绍需要引入的依赖:


<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>

<dependency>
<groupId>io.miniogroupId>
<artifactId>minioartifactId>
<version>8.2.1version>
dependency>

<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>

依赖可以官方文档里找:https://docs.min.io/docs/java-client-quickstart-guide.html

下面介绍配置文件:

spring:
servlet:
multipart:
max-file-size:10MB
max-request-size:10MB
#minio配置
minio:
access-key:AKIAIOSFODNN7EXAMPLE#key就是docker初始化是设置的,密钥相同
secret-key:wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
url:http://localhost:9000
bucket-name:wdhcr
thymeleaf:
cache:false

创建minio的配置类:

@Configuration
@ConfigurationProperties(prefix="spring.minio")
@Data
publicclassMinioConfiguration{
privateStringaccessKey;

privateStringsecretKey;

privateStringurl;

privateStringbucketName;

@Bean
publicMinioClientminioClient(){
returnMinioClient.builder()
.endpoint(url)
.credentials(accessKey,secretKey)
.build();
}
}

使用配置属性绑定进行参数绑定,并初始化一个minio client对象放入容器中。

下面就是我封装的minio client 操作minio的简单方法的组件。

@Component
publicclassMinioComp{

@Autowired
privateMinioClientminioClient;

@Autowired
privateMinioConfigurationconfiguration;

/**
*@description:获取上传临时签名
*@dateTime:2021/5/1314:12
*/
publicMapgetPolicy(StringfileName,ZonedDateTimetime){
PostPolicypostPolicy=newPostPolicy(configuration.getBucketName(),time);
postPolicy.addEqualsCondition("key",fileName);
try{
Mapmap=minioClient.getPresignedPostFormData(postPolicy);
HashMapmap1=newHashMap<>();
map.forEach((k,v)->{
map1.put(k.replaceAll("-",""),v);
});
map1.put("host",configuration.getUrl()+"/"+configuration.getBucketName());
returnmap1;
}catch(ErrorResponseExceptione){
e.printStackTrace();
}catch(InsufficientDataExceptione){
e.printStackTrace();
}catch(InternalExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(InvalidResponseExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(ServerExceptione){
e.printStackTrace();
}catch(XmlParserExceptione){
e.printStackTrace();
}
returnnull;
}

/**
*@description:获取上传文件的url
*@dateTime:2021/5/1314:15
*/
publicStringgetPolicyUrl(StringobjectName,Methodmethod,inttime,TimeUnittimeUnit){
try{
returnminioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(method)
.bucket(configuration.getBucketName())
.object(objectName)
.expiry(time,timeUnit).build());
}catch(ErrorResponseExceptione){
e.printStackTrace();
}catch(InsufficientDataExceptione){
e.printStackTrace();
}catch(InternalExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(InvalidResponseExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(XmlParserExceptione){
e.printStackTrace();
}catch(ServerExceptione){
e.printStackTrace();
}
returnnull;
}


/**
*@description:上传文件
*@dateTime:2021/5/1314:17
*/
publicvoidupload(MultipartFilefile,StringfileName){
//使用putObject上传一个文件到存储桶中。
try{
InputStreaminputStream=file.getInputStream();
minioClient.putObject(PutObjectArgs.builder()
.bucket(configuration.getBucketName())
.object(fileName)
.stream(inputStream,file.getSize(),-1)
.contentType(file.getContentType())
.build());
}catch(ErrorResponseExceptione){
e.printStackTrace();
}catch(InsufficientDataExceptione){
e.printStackTrace();
}catch(InternalExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(InvalidResponseExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(ServerExceptione){
e.printStackTrace();
}catch(XmlParserExceptione){
e.printStackTrace();
}
}
/**
*@description:根据filename获取文件访问地址
*@dateTime:2021/5/1711:28
*/
publicStringgetUrl(StringobjectName,inttime,TimeUnittimeUnit){
Stringurl=null;
try{
url=minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.GET)
.bucket(configuration.getBucketName())
.object(objectName)
.expiry(time,timeUnit).build());
}catch(ErrorResponseExceptione){
e.printStackTrace();
}catch(InsufficientDataExceptione){
e.printStackTrace();
}catch(InternalExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(InvalidResponseExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(XmlParserExceptione){
e.printStackTrace();
}catch(ServerExceptione){
e.printStackTrace();
}
returnurl;
}
}

简单说明:

  • 使用MultipartFile接收前端文件流,再上传到minio。
  • 构建一个formData的签名数据,给前端,让前端之前上传到minio。
  • 构建一个可以上传的临时URL给前端,前端通过携带文件请求该URL进行上传。
  • 使用filename请求服务端获取临时访问文件的URL。(最长时间为7 天,想要永久性访问,需要其他设置,这里不做说明。)

下面展示页面html,使用的是VUE+element-ui进行渲染。

html>
<html>
<head>
<metacharset="UTF-8">

<linkrel="stylesheet"href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<title>上传图片title>
head>
<body>
<divid="app">

<el-row:gutter="2">
<el-col:span="8">
<divclass="div-center-class">
<divclass="">
<center><h3>传统上传h3>center>
<el-upload
class="upload-demo"
action="#"
drag
:http-request="uploadHandle">
<iclass="el-icon-upload">i>
<divclass="el-upload__text">将文件拖到此处,或<em>点击上传em>div>
<divclass="el-upload__tip"slot="tip">只能上传jpg/png文件,且不超过500kbdiv>
el-upload>
<divv-if="imgUrl">
<img:src="imgUrl"style="width:40px;height:40px">img>
div>
div>
div>
el-col>
<el-col:span="8">
<divclass="div-center-class">
<divclass="">
<center><h3>前端formData直传h3>center>
<el-upload
class="upload-demo"
action="#"
drag
:http-request="httpRequestHandle">
<iclass="el-icon-upload">i>
<divclass="el-upload__text">将文件拖到此处,或<em>点击上传em>div>
<divclass="el-upload__tip"slot="tip">只能上传jpg/png文件,且不超过500kbdiv>
el-upload>
<divv-if="directUrl">
<img:src="directUrl"style="width:40px;height:40px">img>
div>
div>
div>
el-col>
<el-col:span="8">
<divclass="div-center-class">
<divclass="">
<center><h3>前端Url直传h3>center>
<el-upload
class="upload-demo"
action="#"
drag
:http-request="UrlUploadHandle">
<iclass="el-icon-upload">i>
<divclass="el-upload__text">将文件拖到此处,或<em>点击上传em>div>
<divclass="el-upload__tip"slot="tip">只能上传jpg/png文件,且不超过500kbdiv>
el-upload>
<divv-if="uploadUrl">
<img:src="uploadUrl"style="width:40px;height:40px">img>
div>
div>
div>
el-col>
el-row>
div>
body>

<scriptsrc="https://unpkg.com/vue/dist/vue.js">script>

<scriptsrc="https://unpkg.com/element-ui/lib/index.js">script>

<scriptsrc="https://unpkg.com/axios/dist/axios.min.js">script>
<script>
newVue({
el:'#app',
data:function(){
return{
imgUrl:'',
directUrl:'',
uploadUrl:''
}
},
methods:{

uploadHandle(options){
let{file}=options;
this.traditionPost(file);
},
traditionPost(file){
_that=this
constform=newFormData();
form.append("fileName",file.name);
form.append("file",file);
this.axiosPost("post","/upload",form).then(function(res){
if(res.status===200){
_that.imgUrl=res.data.data
}else{
alert("上传失败!")
}
})
},
getpolicy(file){
_that=this
axios.get('policy?fileName='+file.name)
.then(function(response){
let{xamzalgorithm,xamzcredential,policy,xamzsignature,xamzdate,host}=response.data.data;
letformData=newFormData();
formData.append("key",file.name);
formData.append("x-amz-algorithm",xamzalgorithm);//让服务端返回200,不设置则默认返回204。
formData.append("x-amz-credential",xamzcredential);
formData.append("policy",policy);
formData.append("x-amz-signature",xamzsignature);
formData.append("x-amz-date",xamzdate);
formData.append("file",file);
//发送POST请求
_that.axiosPost("post",host,formData).then(function(res){
if(res.status===204){
axios.get('url?fileName='+file.name).then(function(res){
_that.directUrl=res.data.data;
})
}else{
alert("上传失败!")
}
})
})
},
httpRequestHandle(options){
let{file}=options;
this.getpolicy(file);
},

UrlUploadHandle(options){
let{file}=options;
this.getUploadUrl(file);
},
getUploadUrl(file){
_that=this
console.log(file)
axios.get('uploadUrl?fileName='+file.name)
.then(function(response){
leturl=response.data.data;
//发送put请求
letconfig={'Content-Type':file.type}
_that.axiosPost("put",url,file,config).then(function(res){
if(res.status===200){
axios.get('url?fileName='+file.name).then(function(res){
_that.uploadUrl=res.data.data;
})
}else{
alert("上传失败!")
}
})
})
},
//封装
//axios封装post请求
axiosPost(method,url,data,config){
letresult=axios({
method:method,
url:url,
data:data,
headers:config
}).then(resp=>{
returnresp
}).catch(error=>{
return"exception="+error;
});
returnresult;
}

}
})
script>
<style>
.div-center-class{
padding:28%0%;
text-align:center;
background:beige;
}
style>
html>

a6a6bd8c-3ae9-11ed-9e49-dac502259ad0.png页面效果

可以分别体验不同的实现效果。

以上就是使用springboot搭建基于minio的高性能存储服务的全部步骤了。

项目地址是:

https://gitee.com/jack_whh/minio-upload



审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 云存储
    +关注

    关注

    7

    文章

    781

    浏览量

    47377
  • 机器学习
    +关注

    关注

    67

    文章

    8562

    浏览量

    137209
  • Docker
    +关注

    关注

    0

    文章

    537

    浏览量

    14398

原文标题:Spring Boot + minio 实现高性能存储服务,So Easy~!

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Docker容器网络模式全解析

    容器网络是Docker使用中最容易出问题的部分。容器之间怎么通信、容器怎么访问外网、外部怎么访问容器内的服务——这三个问题搞不清楚,排查网络故障就是抓瞎。
    的头像 发表于 02-26 16:39 468次阅读

    如何在2026年Rocky Linux(8、9和10)上安装Docker

    Docker 已成为现代应用部署、开发和基础设施自动化的核心技术。如果你在服务器或VPS上运行Rocky Linux,学会在Rocky Linux上安装Docker是你2026年能掌握的最宝贵技能
    的头像 发表于 01-12 17:21 1836次阅读

    如何在NVIDIA Jetson AGX Thor上通过Docker高效部署vLLM推理服务

    继系统安装与环境配置后,本期我们将继续带大家深入 NVIDIA Jetson AGX Thor 的开发教程之旅,了解如何在 Jetson AGX Thor 上,通过 Docker 高效部署 vLLM 推理服务
    的头像 发表于 11-13 14:08 4390次阅读
    如何在NVIDIA Jetson AGX Thor上通过<b class='flag-5'>Docker</b>高效部署vLLM推理<b class='flag-5'>服务</b>

    创龙 瑞芯微 RK3588 国产2.4GHz八核 工业开发板—Docker容器部署方法说明

    本文围绕创龙科技研发的评估板,详细说明 Docker 容器部署方法,包括 Docker 架构介绍、安装步骤(依赖包安装、GPG 密钥添加等)、本地镜像仓库搭建,以及单个 / 多个镜像的构建、推送
    的头像 发表于 10-22 17:21 868次阅读
    创龙 瑞芯微 RK3588 国产2.4GHz八核 工业开发板—<b class='flag-5'>Docker</b>容器部署方法说明

    香港服务器支持Docker和Kubernetes吗?

    在云原生技术成为主流的今天,Docker和Kubernetes(K8s)已成为现代化应用开发和部署的事实标准。对于选择香港服务器的开发者与企业而言,一个核心问题是:香港服务器能否完美支持Doc
    的头像 发表于 10-21 15:47 900次阅读

    【HZ-T536开发板免费体验】Docker 环境安装及应用

    一、检查 Docker 安装状态 板子提示“command not found”或无版本信息,说明 Docker 未安装,如有需要请自行安装 二、Docker 环境安装 首先更新系统包索引并安装
    发表于 09-01 17:59

    Docker容器安全攻防实战案例

    在云原生时代,Docker已成为现代应用部署的基石。然而,容器化带来便利的同时,也引入了新的安全挑战。作为一名在生产环境中管理过数千个容器的运维工程师,我将通过真实的攻防实战案例,带你深入了解Docker安全的每一个细节。
    的头像 发表于 08-05 09:52 1567次阅读

    【VisionFive 2单板计算机试用体验】1. 环境搭建与代码整编

    一、环境搭建 相关命令来源:GitHub - starfive-tech/VisionFive2 注意:整个环境搭建过程都需要vpn,否则ubuntu镜像无法下载,代码无法抓取,编译中间的工具无法
    发表于 07-08 23:07

    恒讯科技分析:云储存服务搭建教程

    搭建云存储服务器是一个相对复杂但极具实用性的项目,以下是一个简化的搭建教程,帮助你快速入门。 一、明确需求 在搭建云存储服务器之前,首先需要
    的头像 发表于 07-07 11:07 1464次阅读

    docker无法启用怎么解决?

    mengxing@mengxing-virtual-machine:/etc/docker$ sudo systemctl daemon-reload
    发表于 06-23 07:17

    迅为RK3576开发板NPUrknn-toolkit2环境搭建和使用docker环境安装

    迅为RK3576开发板NPUrknn-toolkit2环境搭建和使用docker环境安装
    的头像 发表于 06-18 15:22 1462次阅读
    迅为RK3576开发板NPUrknn-toolkit2环境<b class='flag-5'>搭建</b>和使用<b class='flag-5'>docker</b>环境安装

    Docker Volume管理命令大全

    Docker Volume管理命令大全
    的头像 发表于 05-28 17:14 1075次阅读

    如何使用Docker部署大模型

    随着深度学习和大模型的快速发展,如何高效地部署这些模型成为了一个重要的挑战。Docker 作为一种轻量级的容器化技术,能够将模型及其依赖环境打包成一个可移植的容器,极大地简化了部署流程。本文将详细介绍如何使用 Docker 部署大模型,并给出具体的步骤和示例。
    的头像 发表于 05-24 16:39 1342次阅读

    Docker Compose的常用命令

    。它通过一个配置文件(docker-compose.yml)来详细定义多个容器之间的关联、网络设置、服务端口等信息。使用一条简单的命令,就可以轻松启动、停止和管理这些容器,极大地简化了多容器应用的部署与管理流程,方便实现应用的快速构建、开发、测试以及部署。
    的头像 发表于 04-30 13:40 1384次阅读

    Docker基本命令及其用例

    Docker 已迅速成为容器化应用程序的事实标准。作为开发人员或 DevOps 工程师/系统管理员,熟悉 Docker 对于高效部署现代、可移植的应用程序至关重要。
    的头像 发表于 04-30 10:04 838次阅读