1.MinIO是什么?
- MinIO 是一款高性能、分布式的对象存储系统. 它是一款软件产品, 可以100%的运行在标准硬件。即X86等低成本机器也能够很好的运行MinIO。
- MinIO与传统的存储和其他的对象存储不同的是:它一开始就针对性能要求更高的私有云标准进行软件架构设计。因为MinIO一开始就只为对象存储而设计。所以他采用了更易用的方式进行设计,它能实现对象存储所需要的全部功能,在性能上也更加强劲,它不会为了更多的业务功能而妥协,失去MinIO的易用性、高效性。 这样的结果所带来的好处是:它能够更简单的实现局有弹性伸缩能力的原生对象存储服务。
- MinIO在传统对象存储用例(例如辅助存储,灾难恢复和归档)方面表现出色。同时,它在机器学习、大数据、私有云、混合云等方面的存储技术上也独树一帜。当然,也不排除数据分析、高性能应用负载、原生云的支持。
之前我使用的是阿里云OSS,想了解阿里云OSS的小伙伴参考SpringBoot整合阿里云OSS
2.我这里使用的是docker安装方式,使用的前提是小伙伴你已经安装好了一个docker了,关于docker的具体使用可以参考docker的具体使用
3.使用步骤
(1)下载镜像,下载可能有点慢大家等待一下或者配置一下阿里云镜像加速器
docker run -d -p 9000:9000 -p 9001:9001 --name minio -e MINIO_ACCESS_KEY=qbb -e MINIO_SECRET_KEY=startqbb -v /opt/minio/data:/data -v /opt/minio/config:/root/.minio minio/minio server /data --console-address ":9000" --address ":9001"
- MINIO_ACCESS_KEY:指定的是"用户名",可以这么理解,后面我们文件上传需要使用
- MINIO_SECRET_KEY:指定的是"密码",可以这么理解,后面我们文件上传需要使用
下载并运行完成
注意:
-
有可能下载的过程中会出现如下图,minio容器并没有正常启动
docker ps -a
:查看所有容器
-
我们可以使用
docker logs 容器ID(CONTAINERID)
查看一下容器的日志
-
可以看出数data目录没有权限,执行如下命令在启动试试
chmod 777 /opt/minio/data
:设置目录权限为可读可写可执行
docker start 容器ID
:启动容器
(2)我们先在浏览器访问一下http://192.168.137.72:9000/
(3)我们在minio中创建一个bucket
(4)接下来我们创建一个SpringBoot项目
(5)导入相关的依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.qbb</groupId> <artifactId>springboot-minio</artifactId> <version>1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.7.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency> <!--swagger--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.7.0</version> </dependency> <!--swagger ui--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.3.0</version> </dependency> </dependencies> </project>
(6)修改application.yml配置文件
server: port: 7200 spring: application: name: minio app: minio: endpoint: http://192.168.137.72:9001 accessKey: qbb secretKey: startqbb bucket: qbb
注意:9000是我们浏览器访问控制台的端口,而9001是SDK代码操作的端口
(7)主启动类
package com.qbb.minio; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-05-20 15:45 * @Description: */ @SpringBootApplication public class MinioApplication { public static void main(String[] args) { SpringApplication.run(MinioApplication.class, args); } }
(8)这里我配置一个swagger2方便测试,还配置了一个minio的配置类绑定配置文件信息,具体配置如下
package com.qbb.minio.config; import com.google.common.base.Predicates; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-05-20 16:23 * @Description:swagger配置类 */ @Configuration @EnableSwagger2 public class Swagger2Config { @Bean public Docket adminApiConfig() { return new Docket(DocumentationType.SWAGGER_2) .groupName("minioApi") .apiInfo(adminApiInfo()) .select() //只显示admin路径下的页面 .paths(Predicates.and(PathSelectors.regex("/minio/.*"))) .build(); } private ApiInfo adminApiInfo() { return new ApiInfoBuilder() .title("minio-API文档") .version("1.0") .contact(new Contact("QIUQIU&LL", "https://www.cnblogs.com/qbbit", "startqbb@163.com")) .build(); } } package com.qbb.minio.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; /** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-05-20 18:57 * @Description: */ @ConfigurationProperties(prefix = "app.minio") @EnableConfigurationProperties @Configuration @Data public class MinioConfig { private String endpoint; private String accessKey; private String secretKey; private String bucket; }
(9)编写测试代码
package com.qbb.minio.controller; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-05-20 16:23 * @Description: */ @Api(tags = "minio文件管理") @RestController @RequestMapping("/minio") public class FileController { @ApiOperation("测试程序") @GetMapping("/hello") public String hello() { return "hello"; } }
(10)接下来我们编写文件上传代码
package com.qbb.minio.controller; import com.qbb.minio.config.MinioConfig; import io.minio.MinioClient; import io.minio.PutObjectOptions; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.InputStream; import java.util.UUID; /** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-05-20 16:23 * @Description: */ @Api(tags = "minio文件管理") @RestController @RequestMapping("/minio") public class FileController { @Autowired private MinioConfig minioConfig; @ApiOperation("测试程序") @GetMapping("/hello") public String hello() { return "hello"; } @ApiOperation("文件上传") @PostMapping("/fileUpload") public String fileUpload(MultipartFile file) { /** * 这里应该放在service层处理的,将上传的文件路径存入数据库,我就不这么麻烦了,直接返回给前端 */ String bucket = minioConfig.getBucket(); String endpoint = minioConfig.getEndpoint(); String accessKey = minioConfig.getAccessKey(); String secretKey = minioConfig.getSecretKey(); // 1.获取文件名 String originalFilename = file.getOriginalFilename(); // 2.修改文件名,防止上传重复文件名,导致文件覆盖 String fileName = UUID.randomUUID().toString().replace("-", "") + "_" + originalFilename; // 文件流 try (InputStream inputStream = file.getInputStream()) { // 3.使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象 MinioClient minioClient = new MinioClient(endpoint, accessKey, secretKey); // 4.检查存储桶是否已经存在 boolean isExist = minioClient.bucketExists(bucket); if (isExist) { System.out.println("Bucket already exists"); } else { // 不存在则创建一个名为bucket的存储桶,用于存储照片的zip文件。 minioClient.makeBucket(bucket); } // 6.上传参数设置项 PutObjectOptions options = new PutObjectOptions(inputStream.available(), -1); // 7.设置此次上传的文件的内容类型 String contentType = file.getContentType(); options.setContentType(contentType); // 8.上传 minioClient.putObject(bucket, fileName, inputStream, options); // 9.访问路径 String url = endpoint + "/" + bucket + "/" + fileName; return url; } catch (Exception e) { e.printStackTrace(); return null; } } }
(11)使用Swagger测试一下
(12)结果
-
swagger
-
minio控制台
(13)删除minio中的文件
@ApiOperation("删除文件") @DeleteMapping("/remove") public boolean remove() { try { // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象 MinioClient minioClient = new MinioClient(minioConfig.getEndpoint(), minioConfig.getAccessKey(), minioConfig.getSecretKey()); // 从bucket中删除文件(文件名)。 minioClient.removeObject(minioConfig.getBucket(), "ed8aa56a8ec640d6a36a271ed4222605_xiaomi.png"); System.out.println("successfully removed mybucket/myobject"); return true; } catch (Exception e) { System.out.println("Error: " + e); return false; } }
(14)删除后的结果
-
swagger
-
minio控制台
(15)注意:我们配置完了,启动我们的项目可能会出现这么一个错误,说我们的请求时间与服务器时间相差太大
(16)解决办法,linux控制台
yum -y install ntp ntpdate
:安装插件工具
hwclock --systohc
:同步时间
docker restart minio镜像ID
:重启镜像