目录

 

1|0简介

MinIO 是什么?维基百科的解释如下:
MinIO 是 Apache License v2 发布的,与 Amazon S3 兼容的云存储服务器。
作为对象存储,MinIO 可以存储非结构化数据,例如照片,视频,日志文件,备份和容器映像。一个对象的最大大小为 5TB。

2|0安装

MinIO 官方文档:https://docs.min.io/
以下的安装都是基于 Linux(CentOS 7)。

2|1二进制安装

首先,下载二进制文件。
在这里插入图片描述
然后将下载的文件通过 Xftp 上传至 Linux,如下:
我的上传位置为:/usr/local/bin/minio
在这里插入图片描述
然后在上传目录下执行以下命令:

 

# 若已在上传目录下,则不用执行该条命令 cd /usr/local/bin/minio # 给该命令授权 chmod +x minio # 启动 minio,启动时,会自动在磁盘根目录创建 data 文件夹 # data 文件夹就是用来存放上传至 minio服务器的文件 # 如果想要更换 data 的位置,请将其替换为你自己想要的路径,如 /usr/local/data ./minio server /data

如果上述命令执行成功,则会出现以下日志信息:
如果启动后出现警告,提示设置 MINIO_ACCESS_KEY 和 MINIO_SECRET_KEY,解决方式请见后面(其实不用重置密码也可以)。
在这里插入图片描述
然后使用浏览器访问它给出的网址即可,如下:
在这里插入图片描述

如果你使用的是虚拟机搭建 Minio,但是想要在 Windows 上访问此网站,那么,需要进行配置。我在 Linux 网络配置 这篇文章中有提到怎么配置。

输入用户名和密码之后,就可以进入到 MinIO 服务器的 Web 界面,如下(初次进入是一片空白):
在这里插入图片描述
接着,我们就可以上传文件进行测试了,如下:

  • 点击右下角的 + 号
    在这里插入图片描述
  • 选择上传文件
    在这里插入图片描述
    随便选择一个文件上传即可。上传成功之后就可以看到我们上传的文件了,如下:
    在这里插入图片描述
    刚才在启动时,我们有提到一个存储上传文件的 data 文件夹。现在,进入该文件夹,就可以看见我们刚才上传的文件,如下:
    在这里插入图片描述

2|2创建 bucket

当然,我么也可创建 bucket 将这些文件进行分类,如 images,pdf 等,如下:
在这里插入图片描述
然后就可以看见我们刚才创建的 bucket 了:
在这里插入图片描述
也可以对 bucket 进行策略管理:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2|3重置密码

刚才在启动时,出现了一个警告,提示我们重置MINIO_ACCESS_KEY 和 MINIO_SECRET_KEY,现在,就来解决这个问题。先关闭 MinIO 服务,额,由于我们刚才没有设置后台启动 MinIO,导致窗口被占用了(后面会提到设置后台启动),所以,直接使用 Ctrl + C 停止即可。
然后,添加环境变量,执行以下命令:

 

vim /etc/profile

在环境变量中添加以下内容:

 

# 请将以下内容替换为你自己的 export MINIO_ACCESS_KEY=你的用户名 export MINIO_SECRET_KEY=你的密码

然后保存,接着执行以下命令,使环境变量生效:

 

source /etc/profile

然后重新启动 MinIO 即可。

2|4设置后台启动

使用以下命令启动即可:

 

nohup /usr/local/bin/minio/minio server /home/minio/data > /home/minio/data/minio.log 2>&1 &

其中:/home/minio/data/minio.log 是启动时日志文件的存放位置(可以是任意目录),minio.log 需要我们自己手动创建。
到此,MinIO 已经简单的搭建完成。

2|5Docker 安装 MinIO

安装 Docker

首先,我们需要安装 Docker(如已安装,请忽略此步骤)。
要使用Docker,Linux 的系统内核不能低于3.10。

  • 查看内核
 

uname -r

  • 升级内核
 

yum update

  • 安装Docker
 

yum install docker

  • Docker 常用命令
 

# 查看 Docker 版本 docker -v # 启动 Docker systemctl start docker # 设置 docker开机自启 systemctl enable docker # 停止 docker systemctl stop docker # 查看 docker状态 systemctl status docker # 搜索镜像 docekr search xxx # 下载(拉取)镜像 # 格式为 docker pull 镜像名 Name:(tag),其中tag可以用来指定版本 # 默认是下载最新版(即xxx:latest,其中latest可省)。 docker pull mysql:8.0.13 # 查看 Docker中的所有镜像 docker images # 卸载某个镜像 docker rmi IMAGE ID # 其中IMAGE ID为镜像的ID,镜像的ID可以通过docker images命令查看到。 # ----------------------------- # 运行镜像 # 只有镜像被运行了,相应的功能才能被使用。 # 格式:docker run --name 自定义名字 -d REPOSITORY。 # 其中的自定义名字任取,REPOSITORY就是镜像的名字(可以加 tag,即版本;不加则默认是latest,即最新版。--name 自定义名字 可省,-d表示后台运行) docker run --name mytomcat -d tomcat:8.5 # 查询运行中的镜像(即容器) # 使用该命令来查看哪些镜像正在运行。 docker ps # 停止运行的镜像(即容器) docker stop CONTAINER ID # CONTAINER ID就是容器的ID,可以通过docker ps查看到。(也可以使用自定义的名字,如 docker stop mytomcat) # 查看所有容器(不一定在运行) docker ps -a # 启动容器 docker start CONTAINER ID # 停止容器 docker stop CONTAINER ID # 删除容器, 注意:是rm,不是rmi。 docker rm CONTAINER ID # 端口映射 # 容器在虚拟机中运行后,如果不进行端口映射,则在Windows中不能访问。 docker run -d -p 虚拟机中的端口:docker内部的端口 REPOSITORY。# 如 docker run -d -p 8888:8080 tomcat。 # 查看容器日志 docker logs CONTAINER ID

安装 MinIO

执行以下命令下载 MinIO:

 

docker pull minio/minio

启动MinIO(不推荐这样启动,请使用下面的方式进行启动):

 

docker run -p 9000:9000 minio/minio server /data

Docker 运行 MinIO 的注意事项:
MinIO 需要一个持久卷来存储配置和应用数据。不过, 如果只是为了测试一下, 您可以通过简单地传递一个目录(在下面的示例中为/ data)启动MinIO。这个目录会在容器启动时在容器的文件系统中创建,不过所有的数据都会在容器退出时丢失(如上面的启动方式)。

要创建具有永久存储的MinIO容器,您需要将本地持久目录从主机操作系统映射到虚拟配置~/.minio 并导出 /data 目录。 为此,请使用以下命令启动 MinIO:

 

docker run -d -p 9000:9000 --name minio1 \ -e "MINIO_ACCESS_KEY=你的用户名" \ -e "MINIO_SECRET_KEY=你的密码" \ -v /mnt/data:/data \ -v /mnt/config:/root/.minio \ minio/minio server /data

然后就可以通过浏览器进行访问了,数据默认是存在于 /mnt/data 文件夹下。

以上所有配置信息均来自 MinIO 官方文档: https://docs.min.io/

3|0Java API 访问 MinIO

在实际项目中,我们肯定是通过代码来进行文件的上传。为此,MinIO 官网也提供了相应的 API 供我们使用。请见 MinIO SDKS

以下是使用 Spring Boot 调用 Java API 将文件上传至 MinIO。

  • 添加依赖
 

<!-- 添加 minio SDK --> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>7.1.0</version> </dependency> <!-- 添加 thymeleaf,便于测试 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>

  • 配置
 

# 上传文件 spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=100MB # 文件服务器配置 file.bucket-name=testone file.server-path=http://192.168.2.160:9000 file.port=9000 file.access-key=admin file.secure-key=admin123456

  • 对 bucket 进行配置
    在这里插入图片描述
  • 核心代码
@RestController
@RequestMapping("/upload")
public class MinioController {

    @Autowired
    private FileUtil fileUtil;

    @Autowired
    private FileProperties fileProperties;

    @Autowired
    private MinioClient minioClient;

    @PostMapping("/test6")
    public Result upload6(@RequestParam("file") MultipartFile file) throws Exception{
        if (file.getSize() > 0) {
            String bucketName = fileProperties.getBucketName();
            boolean isExist = minioClient.bucketExists(bucketName);
            if (!isExist) {
                minioClient.makeBucket(bucketName);
            }
            // 原文件名
            String fileName = file.getOriginalFilename();
            // 文件类型
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            // 生成新文件名,确保唯一性
            String objectName = UUID.randomUUID().toString() + suffixName;
            // 文件类型
            String fileType = file.getContentType();
            // 使用putObject上传一个文件到存储桶中
            minioClient.putObject(bucketName, objectName, file.getInputStream(), fileType);
            // 得到文件 url
            String imageUrl = minioClient.getObjectUrl(bucketName, objectName);
            // 生成下载链接
            String downloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
                    .path("/upload/downloadFile/")
                    .path(objectName)
                    .toUriString();
            return Result.success(new FileUploadResult(fileName, file.getSize(), fileType, objectName, imageUrl, downloadUri));
        }
        return Result.error("未选择任何文件,上传失败");
    }

    // 正则表达式,然后结果存在filename 这个变量里
    // 比如 /downloadFile/123q, 那么 fileName 就是 123q
    @GetMapping("/downloadFile/{fileName:.+}")
    public ResponseEntity<Resource> downloadFile(@PathVariable String fileName, HttpServletRequest request) throws Exception{
        String url = fileProperties.getServerPath() + "/" + fileProperties.getBucketName() + "/" + fileName;
        Resource resource = fileUtil.loadUrlAsResource(url);

        String contentType = null;
        try {
            contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
        } catch (IOException ex) {
        }

        if(contentType == null) {
            contentType = "application/octet-stream";
        }

        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(contentType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
                .body(resource);
    }
}

注意,使用 application/octet-stream 上传时, 浏览器打开链接会默认进行下载而不是在浏览器中浏览该文件。所以,我在上传时,使用的是 file.getContentType() 得到文件的类型,进行上传,这样通过返回的 URL 就可以直接预览该文件,但是,使用 presignedGetObject() 方法就无法进行文件的下载,它返回的链接还是只能进行预览,所以,我就写了downloadFile() 方法进行文件下载,并返回下载的 URL。

完整代码请见:

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐