MinIO的搭建
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MinIO的搭建相关的知识,希望对你有一定的参考价值。
参考技术A MinIO是在GUN Affero通用公共许可证v3.0下发布的高性能的对象存储。它是与Amazon S3云存储服务兼容的API。使用MinIO为机器学习、分析和隐月宫程序数据工作负载构建高性能基础架构。
MinIO对象存储使用buckets(桶)来组织对象,桶类似于文件系统中的目录/文件夹,可以存放任意数量的对象,它提供与 AWS S3 buckets 相同的功能。
bucket多版本存储:MinIO支持同一个对象在一个桶中存在多个版本。
安装(rpm方法):
启动:
添加防火墙端口9000和9001
添加主机名
之后就可以通过 server1:9000 来访问 MinIO 控制台了
后续还可以通过server2、server3来命名其他主机,从而可以通过server1…3来指定3个服务器。
其中:
搭建文件服务器 MinIO
1 下载
minio官方文档
我选择的是docker部署
docker pull minio/minio
docker run \\
-p 9000:9000 \\
-p 9001:9001 \\
--name minio1 \\
-v ~/minio/data:/data \\
-e "MINIO_ROOT_USER=username" \\
-e "MINIO_ROOT_PASSWORD=password" \\
-d \\
quay.io/minio/minio server /data --console-address ":9001"
访问http://101.42.135.107:9001/
进入控制台界面 ( 如果是云服务器记得打开9001端口)
2 上传文件到minio
创建名为hms的桶
然后上传一个图片
设置访问规则:
添加只读属性,前缀为 “*”,这样就可以浏览器访问了
2 SpringBoot整合
2.1 依赖,主启动
最开始用的8.3.7, 和我的jar包冲突了,又换成8.2.1
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.1</version>
</dependency>
2.2 配置文件
server:
port: 9201
spring:
application:
name: file
datasource:
username: root
password: 18170021
url: jdbc:mysql://localhost:3306/db_hms_file?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
cloud:
nacos:
server-addr: localhost:8848
# 配置文件大小限制
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
minio:
# minio配置是自定义的配置,注意:一定加http://
endpoint: http://localhost:9000
accessKey: root
secretKey: root18170021
bucketName: hms
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
2.3 Minio客户端配置类
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioClientConfig
private String endpoint;
private String accessKey;
private String secretKey;
@Bean
public MinioClient minioClient()
MinioClient minioClient = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
return minioClient;
2.4 工具类
不要被吓跑哦,我只用到其中的上传下载删除三个方法,不过以后可能会用到就都copy过来了
@Component
public class MinioUtil
@Autowired
private MinioClient minioClient;
/**
* 查看存储bucket是否存在
* @return boolean
*/
public Boolean bucketExists(String bucketName)
Boolean found;
try
found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
catch (Exception e)
return false;
return found;
/**
* 创建存储bucket
* @return Boolean
*/
public Boolean makeBucket(String bucketName)
try
minioClient.makeBucket(MakeBucketArgs.builder()
.bucket(bucketName)
.build());
catch (Exception e)
e.printStackTrace();
return false;
return true;
/**
* 删除存储bucket
* @return Boolean
*/
public Boolean removeBucket(String bucketName)
try
minioClient.removeBucket(RemoveBucketArgs.builder()
.bucket(bucketName)
.build());
catch (Exception e)
e.printStackTrace();
return false;
return true;
/**
* 获取全部bucket
*/
public List<Bucket> getAllBuckets()
try
return minioClient.listBuckets();
catch (Exception e)
e.printStackTrace();
return null;
/**
* 文件上传
* @param file 文件
* @return Boolean
*/
public Boolean upload(String bucketName, String fileName, MultipartFile file, InputStream inputStream)
try
PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName)
.stream(inputStream,file.getSize(),-1).contentType(file.getContentType()).build();
//文件名称相同会覆盖
minioClient.putObject(objectArgs);
catch (Exception e)
e.printStackTrace();
return false;
return true;
/**
* 预览图片
* @param fileName
* @return
*/
public String preview(String fileName,String bucketName)
// 查看文件地址
GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs
.builder().bucket(bucketName)
.object(fileName)
.method(Method.GET).build();
try
String url = minioClient.getPresignedObjectUrl(build);
return url;
catch (Exception e)
e.printStackTrace();
return null;
/**
* 文件下载
* @param fileName 文件名称
* @param res response
* @return Boolean
*/
public void download(String fileName,String bucketName, HttpServletResponse res)
GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName)
.object(fileName).build();
try (GetObjectResponse response = minioClient.getObject(objectArgs))
byte[] buf = new byte[1024];
int len;
try (FastByteArrayOutputStream os = new FastByteArrayOutputStream())
while ((len=response.read(buf))!=-1)
os.write(buf,0,len);
os.flush();
byte[] bytes = os.toByteArray();
res.setCharacterEncoding("utf-8");
//设置强制下载不打开
//res.setContentType("application/force-download");
res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
try (ServletOutputStream stream = res.getOutputStream())
stream.write(bytes);
stream.flush();
catch (Exception e)
e.printStackTrace();
/**
* 查看文件对象
* @return 存储bucket内文件对象信息
*/
public List<Item> listObjects(String bucketName)
Iterable<Result<Item>> results = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucketName).build());
List<Item> items = new ArrayList<>();
try
for (Result<Item> result : results)
items.add(result.get());
catch (Exception e)
e.printStackTrace();
return null;
return items;
/**
* 删除
* @param fileName
* @return
* @throws Exception
*/
public boolean remove(String fileName,String bucketName)
try
minioClient.removeObject( RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());
catch (Exception e)
return false;
return true;
/**
* 批量删除文件对象(没测试)
* @param objects 对象名称集合
*/
public Iterable<Result<DeleteError>> removeObjects(List<String> objects, String bucketName)
List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
return results;
2.5 Controller
@RestController
@RequestMapping("file")
public class FileController
private static final Logger log = LogManager.getLogger();
@Autowired
private FileItemServiceImpl fileItemService;
@PostMapping("upload")
public Result upload(@Valid @NotNull @RequestParam(value = "file") MultipartFile file, @Valid @NotNull Integer type)
Result result;
try
FileItemVO fileItemVO = fileItemService.uploadFile(file, type);
result = Result.success("文件上传成功!", fileItemVO);
catch (BcException e)
result = Result.error(e.getCode(), e.getMessage());
log.error(e.getMessage());
return result;
@GetMapping("download")
public void download(HttpServletResponse response,
@Valid @RequestParam @NotBlank(message = "fileId不能为空") Integer fileId)
try
fileItemService.downloadFile(fileId, response);
catch (BcException e)
log.error(e.getMessage());
@GetMapping("delete")
public Result<String> delete(@Valid @RequestParam @NotBlank(message = "fileId不能为空") Long fileId)
Result result;
try
fileItemService.deleteFile(fileId);
result = Result.success("删除附件成功!", fileId);
catch (BcException e)
result = Result.error(e.getCode(), e.getMessage());
return result;
2.6 Service
service
public interface FileItemService
/**
* 上传文件到服务器中
* @param file
* @param type
* @return
*/
FileItemVO uploadFile(MultipartFile file, Integer type);
/**
* 下载文件
* @param fileId
* @param response
*/
void downloadFile(Integer fileId, HttpServletResponse response);
/**
* 删除文件
* @param fileId
*/
void deleteFile(Long fileId);
serviceImpl
@Service
public class FileItemServiceImpl implements FileItemService
@Resource
private MinioUtil minioUtil;
@Value("$minio.bucketName")
private String bucketName;
@Value("$minio.endpoint")
private String endpoint;
@Autowired
private FileMapper fileMapper;
private String[] fileFolders = new String[]"doctorPhotos/", "report", "otherImage/";
@Override
@Transactional(rollbackFor = Exception.class)
public FileItemVO uploadFile(MultipartFile file, Integer type)
FileItemVO fileItemVO = null;
try
String fileName = file.getOriginalFilename();
String ext = fileName.substring(fileName.lastIndexOf("."));
String newFileName = fileFolders[type] + UUID.randomUUID().toString().replaceAll("-", "") + ext;
InputStream inputStream = file.getInputStream();
Boolean flag = minioUtil.upload(bucketName, newFileName,file, inputStream);
if(!flag)
throw new BcException(ErrorCode.file_upload_fail.getCode(), "文件上传失败");
String url = getUrl(newFileName);
fileItemVO = FileItemVO.builder()
.newFileName(newFileName)
.fileName(fileName)
.ext(ext)
.url(url)
.build();
FileEntity fileEntity = new FileEntity();
BeanUtils.copyProperties(fileItemVO, fileEntity);
fileEntity.setType(type);
fileMapper.insert(fileEntity);
fileItemVO.setFileId(fileEntity.getId());
catch (Exception e)
throw new BcException(ErrorCode.file_upload_fail.getCode(), "文件上传失败");
return fileItemVO;
@Transactional(readOnly = true)
@Override
public void downloadFile(Integer fileId, HttpServletResponse response)
FileEntity fileEntity = fileMapper.selectById(fileId);
if(ObjectUtils.isEmpty(fileEntity))
throw new BcException(ErrorCode.file_not_exit.getCode(), "文件不存在");
try
minioUtil.download(fileEntity.getNewFileName(), bucketName, response);
catch (Exception e)
throw new BcException(ErrorCode.download_id_exception.getCode(), "文件下载失败");
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteFile(Long fileId)
FileEntity fileEntity = fileMapper.selectById(fileId);
if(ObjectUtils.isEmpty(fileEntity))
throw new BcException(ErrorCode.file_not_exit.getCode(), "文件不存在");
try
minioUtil.remove(fileEntity.getNewFileName(), bucketName);
fileMapper.deleteById(fileId);
catch (Exception e)
throw new BcException(ErrorCode.download_id_exception.getCode(), "文件删除失败");
private String getUrl(String newFileName)
return endpoint
+ "/"
+ bucketName
+ "/"
+ newFileName;
2.7 实体和数据库
FileItemVO (上传文件后响应结果)
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class FileItemVO
/**
* 文件id
*/
private Long fileId;
/**
* 文件可访问URL
*/
private String url;
/**
* 文件的拓展名
*/
private String ext;
/**
* 上传的源文件的文件名,带有拓展
*/
private String fileName;
/**
* 上传后的文件名
*/
private String newFileName;
file表
DROP TABLE IF EXISTS `file`;
CREATE TABLE `file` (
`id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT \'id\',
`file_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT \'用户上传文件的原始名称,带有文件拓展\',
`ext` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT \'文件拓展名\',
`type` int(0) NOT NULL COMMENT \'文件类型:1医生照片 2其他图片 3体检报告\',
`url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT \'url\',
`new_file_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT \'minio里面的文件名\',
`created_time` datetime(0) NOT NULL COMMENT \'创建时间\',
`modified_time` datetime(0) NOT NULL COMMENT \'修改时间\',
`state` int(0) NOT NULL DEFAULT 0 COMMENT \'状态\',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
2.8 参考链接
以上是关于MinIO的搭建的主要内容,如果未能解决你的问题,请参考以下文章