简介
Minio是一个高性能、开源的 S3 兼容对象存储系统,采用 Go 语言编写,支持分布式部署。具有如下特点:
1、支持离线部署,可在本地 NAS 或服务器上运行;
2、提供 Web 控制台,管理存储桶和访问密钥;
3、兼容 AWS S3 API,便于集成现有应用;
官方文档:minio documentation
Docker部署
1、拉取minio镜像
docker search minio docker pull minio/minio
2、创建容器
#创建需要挂载的文件夹 mkdir -p /root/home/minio/data mkdir -p /root/home/minio/config docker run -p 9010:9000 -p 9011:9001 --name minio \ --restart=always \ --privileged=true \ -v /root/home/minio/data:/data \ -v /root/home/minio/config:/root/.minio \ -e "MINIO_ACCESS_KEY=minioImooc" \ -e "MINIO_SECRET_KEY=idcbgp.cn" \ -e "MINIO_CONSOLE_ADDRESS=:9001" \ -d quay.io/minio/minio:RELEASE.2025-04-08T15-41-24Z server /data \ --console-address ":9001"
命令解释
-p 9010:9000 #API端口,因为服务器9000端口被占用了,所以改成9010端口了 -p 9011:9001 #控制台端口 --restart=always #重启策略,开机自动启动,不需要可以删掉 --privileged=true #权限 -e "MINIO_ACCESS_KEY=minioImooc" #access key,类似于登录账户 -e "MINIO_SECRET_KEY=idcbgp.cn" #secret key,类似于登录密码 -e "MINIO_CONSOLE_ADDRESS=:9001" #指定控制台端口
创建成功后需开放9010和9011端口。
sudo firewall-cmd --zone=public --add-port=9010/tcp --permanent sudo firewall-cmd --zone=public --add-port=9011/tcp --permanent sudo firewall-cmd --reload
访问地址:http://ip:9011。
创建一个公开的bucket
1、创建一个bucket
首先登录minio控制台,账户密码就是刚才配置的access_key和secret_key。路径:Buckets->Create Bucket。
2、访问策略设为公开。如果不设置公开,则无法拿到长期有效的文件访问连接。
3、创建access key,用于api调用
Spring 集成minio
1、添加依赖
pom.xml
<!-- MinIO Java SDK --> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.5.7</version> </dependency>
2、配置Minio信息
application.yaml
minio: endpoint: http://ip:port access-key: your_access_value secret-key: your_secret_value bucket-name: your_bucket_name
3、创建Minio配置类
import lombok.Getter; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Getter @Component public class MinioOptions { @Value("${minio.endpoint}") private String endpoint; @Value("${minio.access-key}") private String accessKey; @Value("${minio.secret-key}") private String secretKey; @Value("${minio.bucket-name}") private String bucketName; }
import io.minio.MinioClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MinioConfig { private final MinioOptions minioOptions; public MinioConfig(MinioOptions minioOptions) { this.minioOptions = minioOptions; } @Bean public MinioClient minioClient(){ return MinioClient.builder() .endpoint(minioOptions.getEndpoint()) .credentials(minioOptions.getAccessKey(), minioOptions.getSecretKey()) .build(); } }
4、创建Minio service类
import io.minio.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.compress.utils.IOUtils; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import java.io.InputStream; import java.util.Base64; @Slf4j @Service @RequiredArgsConstructor public class MinioService { private final MinioClient minioClient; private final MinioOptions minioOptions; //上传图片 public String uploadImage(MultipartFile file,String objectName) { try { //检查bucket是否存在,不存在则创建 boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioOptions.getBucketName()).build()); if (!found) { minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioOptions.getBucketName()).build()); } //上传图片 minioClient.putObject( PutObjectArgs.builder() .bucket(minioOptions.getBucketName()) .object(objectName) .stream(file.getInputStream(),file.getSize(),-1) .contentType(file.getContentType()) .build()); //获取图片url return String.format("%s/%s/%s", minioOptions.getEndpoint(), minioOptions.getBucketName(), objectName); } catch (Exception e){ log.error("上传图片失败:{}",e.getMessage()); throw new RuntimeException("上传图片失败",e); } } public void deleteImageByUrl(String imageUrl) { String objectName = getObjectName(imageUrl); deleteImage(objectName); } //删除图片 public void deleteImage(String objectName) { try { minioClient.removeObject( RemoveObjectArgs.builder() .bucket(minioOptions.getBucketName()) .object(objectName) .build()); } catch (Exception e){ log.error("删除图片失败:{}",e.getMessage()); throw new RuntimeException("删除图片失败",e); } } public String getImageAsBase64ByUrl(String imageUrl) { String objectName = getObjectName(imageUrl); return getImageAsBase64(objectName); } //图片转Base64 public String getImageAsBase64(String objectName) { try (InputStream stream = minioClient.getObject( GetObjectArgs.builder() .bucket(minioOptions.getBucketName()) .object(objectName) .build())) { byte[] bytes = IOUtils.toByteArray(stream); return Base64.getEncoder().encodeToString(bytes); } catch (Exception e) { log.error("获取图片Base64失败: {}", e.getMessage()); throw new RuntimeException("获取图片Base64失败", e); } } public String getObjectName(String imageUrl) { if (!StringUtils.hasText(imageUrl)) { return ""; } // 找到最后一个"/"的位置 int lastSlashIndex = imageUrl.lastIndexOf('/'); if (lastSlashIndex == -1) { return ""; } return imageUrl.substring(lastSlashIndex + 1); } }
5、创建控制器
import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import withub.framework.utils.StringTool; import withub.gs.application.externalService.minio.MinioService; import withub.gs.contract.param.staff.FaceUploadParam; import withub.gs.contract.param.staff.FileDelParam; import java.util.Objects; @Slf4j @RestController @RequestMapping(ADMIN_V1 + "/file") public class FileController { private final MinioService minioService; public FileController(MinioService minioService) { this.minioService = minioService; } @Operation(summary = "删除文件") @PostMapping("/delete") public void deleteImageFile(@RequestBody FileDelParam request) { String objectName = minioService.getObjectName(request.path); minioService.deleteImage(objectName); } @Operation(summary = "上传图片") @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public String uploadImageFile(@RequestParam("file") MultipartFile file) { return minioService.uploadImage(file, System.currentTimeMillis() + ".jpg"); } @Operation(summary = "图片转base64") @PostMapping("/faceBase64") public String urlToBase64(@RequestBody FaceUploadParam param) { String objectName = minioService.getObjectName(param.getFileUrl()); return minioService.getImageAsBase64(objectName); } }
點擊查看更多內(nèi)容
為 TA 點贊
評論
評論
共同學(xué)習(xí),寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章
正在加載中
感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦