您的位置:首页 > 娱乐 > 八卦 > minio

minio

2025/2/23 7:33:02 来源:https://blog.csdn.net/m0_66052129/article/details/139610944  浏览:    关键词:minio

Docker安装minio,搭建自己的oss服务器

docker search minio

docker pull minio/minio
docker run -p 9000:9000 -p 9090:9090 \--name minio \-d --restart=always \-e "MINIO_ACCESS_KEY=minioadmin" \-e "MINIO_SECRET_KEY=minioadmin" \-v /mydata/minio/data:/data \minio/minio server \/data --console-address ":9090" -address ":9000"

启动后,访问机器ip+9090,进入minio的界面,输入用户名或密码后可以访问。

Docker安装miniomc突破7天限制 

docker pull minio/mcdocker run -it --entrypoint=/bin/sh minio/mcmc config host add <ALIAS> <YOUR-S3-ENDPOINT> <YOUR-ACCESS-KEY> <YOUR-SECRET-KEY> [--api API-SIGNATURE]mc config host add minio http://117.72.14.166:9000 GrVCPXySKgGoJiGgXmtv 0xlqSI9GXvnBOtp0GwUj5OshKNBk9JgwoexotbVVmc ls miniomc anonymousmc anonymous set download minio/jichi

oss 模块设计

image.png


注意:考虑 oss 的扩展性和切换性。
目前对接的 minio,要考虑,如果作为公共的 oss 服务,如何切换到其他的阿里云 oss 或者对接京东云的 oss。作为基础的 oss 服务,切换等等动作,不应该要求业务方进行改造,以及对切换有感知。

oss 模块集成代码
feat:oss文件服务
feat:oos集成后测试
适配器模式实现 oss 代码

适配器模式用于:接口不符

oss配合nacos实现动态切换

nacos 作为配置中心,可以实现动态配置,适用于比如动态数据源切换,动态切换 oss。
详细可以看代码。
feat:集成nacos动态配置
feat:版本调整
feat:nacos实现文件bean动态切换
代码配置
新建 bootstrap 文件

spring:application:name: jc-club-ossprofiles:active: devcloud:nacos:config:server-addr: 117.72.14.166:8848prefix: ${spring.application.name}group: DEFAULT_GROUPnamespace:file-extension: yaml

image.png

image.png


新建配置

详情示例代码编辑删除

image.png

代码:

package com.jingdianjichi.oss.entity;/*** 文件类**/
public class FileInfo {private String fileName;private Boolean directoryFlag;private String etag;public String getFileName() {return fileName;}public void setFileName(String fileName) {this.fileName = fileName;}public Boolean getDirectoryFlag() {return directoryFlag;}public void setDirectoryFlag(Boolean directoryFlag) {this.directoryFlag = directoryFlag;}public String getEtag() {return etag;}public void setEtag(String etag) {this.etag = etag;}
}
package com.jingdianjichi.oss.entity;import lombok.Data;@Data
public class Result<T> {private Boolean success;private Integer code;private String message;private T data;public static Result ok(){Result result = new Result();result.setSuccess(true);result.setCode(ResultCodeEnum.SUCCESS.getCode());result.setMessage(ResultCodeEnum.SUCCESS.getDesc());return result;}public static <T> Result ok(T data){Result result = new Result();result.setSuccess(true);result.setCode(ResultCodeEnum.SUCCESS.getCode());result.setMessage(ResultCodeEnum.SUCCESS.getDesc());result.setData(data);return result;}public static Result fail(){Result result = new Result();result.setSuccess(false);result.setCode(ResultCodeEnum.FAIL.getCode());result.setMessage(ResultCodeEnum.FAIL.getDesc());return result;}public static <T> Result fail(T data){Result result = new Result();result.setSuccess(false);result.setCode(ResultCodeEnum.FAIL.getCode());result.setMessage(ResultCodeEnum.FAIL.getDesc());result.setData(data);return result;}}
package com.jingdianjichi.oss.entity;import lombok.Getter;@Getter
public enum ResultCodeEnum {SUCCESS(200,"成功"),FAIL(500,"失败");public int code;public String desc;ResultCodeEnum(int code,String desc){this.code = code;this.desc = desc;}public static ResultCodeEnum getByCode(int codeVal){for(ResultCodeEnum resultCodeEnum : ResultCodeEnum.values()){if(resultCodeEnum.code == codeVal){return resultCodeEnum;}}return null;}}

 

package com.jingdianjichi.oss.adapter;import com.jingdianjichi.oss.entity.FileInfo;
import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;
import java.util.List;/*** 文件存储适配器*/
public interface StorageAdapter {/*** 创建bucket桶*/void createBucket(String bucket);/*** 上传文件*/void uploadFile(MultipartFile uploadFile, String bucket, String objectName);/*** 列出所有桶*/List<String> getAllBucket();/*** 列出当前桶及文件*/List<FileInfo> getAllFile(String bucket);/*** 下载文件*/InputStream downLoad(String bucket, String objectName);/*** 删除桶*/void deleteBucket(String bucket);/*** 删除文件*/void deleteObject(String bucket, String objectName);String getUrl(String bucket, String objectName);}
package com.jingdianjichi.oss.adapter;import com.jingdianjichi.oss.entity.FileInfo;
import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;/*** 阿里云oss适配器**/
public class AliStorageAdapter implements StorageAdapter {@Overridepublic void createBucket(String bucket) {}@Overridepublic void uploadFile(MultipartFile uploadFile, String bucket, String objectName) {}@Overridepublic List<String> getAllBucket() {List<String> bucketNameList = new LinkedList<>();bucketNameList.add("aliyun");return bucketNameList;}@Overridepublic List<FileInfo> getAllFile(String bucket) {return null;}@Overridepublic InputStream downLoad(String bucket, String objectName) {return null;}@Overridepublic void deleteBucket(String bucket) {}@Overridepublic void deleteObject(String bucket, String objectName) {}@Overridepublic String getUrl(String bucket, String objectName) {return null;}}
package com.jingdianjichi.oss.adapter;import com.jingdianjichi.oss.entity.FileInfo;
import com.jingdianjichi.oss.util.MinioUtil;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.io.InputStream;
import java.util.List;/*** minioIO存储适配器**/
public class MinioStorageAdapter implements StorageAdapter {@Resourceprivate MinioUtil minioUtil;/*** minioUrl*/@Value("${minio.url}")private String url;@Override@SneakyThrowspublic void createBucket(String bucket) {minioUtil.createBucket(bucket);}@Override@SneakyThrowspublic void uploadFile(MultipartFile uploadFile, String bucket, String objectName) {minioUtil.createBucket(bucket);if (objectName != null) {minioUtil.uploadFile(uploadFile.getInputStream(), bucket, objectName + "/" + uploadFile.getOriginalFilename());} else {minioUtil.uploadFile(uploadFile.getInputStream(), bucket, uploadFile.getOriginalFilename());}}@Override@SneakyThrowspublic List<String> getAllBucket() {return minioUtil.getAllBucket();}@Override@SneakyThrowspublic List<FileInfo> getAllFile(String bucket) {return minioUtil.getAllFile(bucket);}@Override@SneakyThrowspublic InputStream downLoad(String bucket, String objectName) {return minioUtil.downLoad(bucket, objectName);}@Override@SneakyThrowspublic void deleteBucket(String bucket) {minioUtil.deleteBucket(bucket);}@Override@SneakyThrowspublic void deleteObject(String bucket, String objectName) {minioUtil.deleteObject(bucket, objectName);}@Override@SneakyThrowspublic String getUrl(String bucket, String objectName) {return url + "/" + bucket + "/" + objectName;}}

 

package com.jingdianjichi.oss.config;import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** minio配置管理**/
@Configuration
public class MinioConfig {/*** minioUrl*/@Value("${minio.url}")private String url;/*** minio账户*/@Value("${minio.accessKey}")private String accessKey;/*** minio密码*/@Value("${minio.secretKey}")private String secretKey;/*** 构造minioClient*/@Beanpublic MinioClient getMinioClient() {return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();}}
package com.jingdianjichi.oss.config;import com.jingdianjichi.oss.adapter.StorageAdapter;
import com.jingdianjichi.oss.adapter.AliStorageAdapter;
import com.jingdianjichi.oss.adapter.MinioStorageAdapter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 文件存储config**/
@Configuration
@RefreshScope
public class StorageConfig {@Value("${storage.service.type}")private String storageType;@Bean@RefreshScopepublic StorageAdapter storageService() {if ("minio".equals(storageType)) {return new MinioStorageAdapter();} else if ("aliyun".equals(storageType)) {return new AliStorageAdapter();} else {throw new IllegalArgumentException("未找到对应的文件存储处理器");}}}

package com.jingdianjichi.oss.controller;import com.jingdianjichi.oss.entity.Result;
import com.jingdianjichi.oss.service.FileService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.util.List;/*** 文件操作controller**/
@RestController
public class FileController {@Resourceprivate FileService fileService;@RequestMapping("/testGetAllBuckets")public String testGetAllBuckets() throws Exception {List<String> allBucket = fileService.getAllBucket();return allBucket.get(0);}@RequestMapping("/getUrl")public String getUrl(String bucketName, String objectName) throws Exception {return fileService.getUrl(bucketName, objectName);}/*** 上传文件*/@RequestMapping("/upload")public Result upload(MultipartFile uploadFile, String bucket, String objectName) throws Exception {String url = fileService.uploadFile(uploadFile, bucket, objectName);return Result.ok(url);}}

package com.jingdianjichi.oss.service;import com.jingdianjichi.oss.adapter.StorageAdapter;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.util.List;/*** 文件存储service**/
@Service
public class FileService {private final StorageAdapter storageAdapter;public FileService(StorageAdapter storageAdapter) {this.storageAdapter = storageAdapter;}/*** 列出所有桶*/public List<String> getAllBucket() {return storageAdapter.getAllBucket();}/*** 获取文件路径*/public String getUrl(String bucketName,String objectName) {return storageAdapter.getUrl(bucketName,objectName);}/*** 上传文件*/public String uploadFile(MultipartFile uploadFile, String bucket, String objectName){storageAdapter.uploadFile(uploadFile,bucket,objectName);objectName = objectName + "/" + uploadFile.getOriginalFilename();return storageAdapter.getUrl(bucket, objectName);}
}

package com.jingdianjichi.oss;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;/*** oss服务启动器**/
@SpringBootApplication
@ComponentScan("com.jingdianjichi")
public class OssApplication {public static void main(String[] args) {SpringApplication.run(OssApplication.class);}}
package com.jingdianjichi.oss.util;import com.jingdianjichi.oss.entity.FileInfo;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;/*** minio文件操作工具**/
@Component
public class MinioUtil {@Resourceprivate MinioClient minioClient;/*** 创建bucket桶*/public void createBucket(String bucket) throws Exception {boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());if (!exists) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());}}/*** 上传文件*/public void uploadFile(InputStream inputStream, String bucket, String objectName) throws Exception {minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName).stream(inputStream, -1, 5242889L).build());}/*** 列出所有桶*/public List<String> getAllBucket() throws Exception {List<Bucket> buckets = minioClient.listBuckets();return buckets.stream().map(Bucket::name).collect(Collectors.toList());}/*** 列出当前桶及文件*/public List<FileInfo> getAllFile(String bucket) throws Exception {Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucket).build());List<FileInfo> fileInfoList = new LinkedList<>();for (Result<Item> result : results) {FileInfo fileInfo = new FileInfo();Item item = result.get();fileInfo.setFileName(item.objectName());fileInfo.setDirectoryFlag(item.isDir());fileInfo.setEtag(item.etag());fileInfoList.add(fileInfo);}return fileInfoList;}/*** 下载文件*/public InputStream downLoad(String bucket, String objectName) throws Exception {return minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(objectName).build());}/*** 删除桶*/public void deleteBucket(String bucket) throws Exception {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());}/*** 删除文件*/public void deleteObject(String bucket, String objectName) throws Exception {minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build());}/*** 获取文件url*/public String getPreviewFileUrl(String bucketName, String objectName) throws Exception{GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucketName).object(objectName).build();return minioClient.getPresignedObjectUrl(args);}}

server:port: 4000
minio:url: http://192.168.200.177:9000accessKey: minioadminsecretKey: minioadmin
spring:application:name: jc-club-oss-devprofiles:active: devcloud:nacos:config:server-addr: 192.168.200.177:8848prefix: ${spring.application.name}group: DEFAULT_GROUPnamespace:file-extension: yamldiscovery:enabled: trueserver-addr: 192.168.200.177:8848

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com