专栏首页ai_houzi记对象存储服务——Minio的使用

记对象存储服务——Minio的使用

Minio

Minio 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。 

Minio是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。

Minio不仅提供了服务器、Web访问、客户端,还提供了Docker安装,各种语言的SDK、实例、实战秘籍等等,支持分布式部署,[官方文档](https://docs.minio.io)一应俱全。

Minio安装

Minio各个系统的安装均非常简单,这里仅介绍MacOS系统的安装,其他系统[官方文档](https://docs.minio.io)均有详细介绍,这里不再过多赘述。

MacOS

Homebrew

Install minio packages using Homebrew

brew install minio/stable/minio
minio server /data

NOTE: If you previously installed minio using brew install minio then it is recommended that you reinstall minio from minio/stable/minio official repo instead.

brew uninstall minio
brew install minio/stable/minio

Binary Download

Platform

Architecture

URL

Apple macOS

64-bit Intel

https://dl.minio.io/server/minio/release/darwin-amd64/minio

chmod 755 minio
./minio server /data

Minio Web

安装后运行启动命令,启动成功后使用浏览器访问http://127.0.0.1:9000,如果可以访问,则表示Minio已安装成功。
输入运行时生成的两个Key便可以成功访问:

Minio Server

Minio server在默认情况下会将所有配置信息存到 `${HOME}/.minio/config.json` 文件中。 以下部分提供每个字段的详细说明以及如何自定义它们。一个完整的 `config.json` 在 [这里](https://raw.githubusercontent.com/minio/minio/master/docs/config/config.sample.json)

配置目录

默认的配置目录是 `${HOME}/.minio`,你可以使用`--config-dir`命令行选项重写之。 Minio server在首次启动时会生成一个新的`config.json`,里面带有自动生成的访问凭据。
minio server --config-dir /etc/minio /data

配置参数

详见官方文档,[Minio Server Config Guide](https://docs.minio.io/docs/minio-server-configuration-guide.html)

Minio 客户端

Minio客户端,Minio Client (mc)为ls,cat,cp,mirror,diff,find等UNIX命令提供了一种替代方案。它支持文件系统和兼容Amazon S3的云存储服务(AWS Signature v2和v4)。详见官方文档,[Minio Client Quickstart Guide](https://docs.minio.io/docs/minio-client-quickstart-guide.html)

Minio SDK

Minio官方文档为各种语言提供了SDK及详细的接口说明。

Spring boot 集成

最低要求:

  • Java1.8以上

Maven:

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>3.0.10</version>
 </dependency>

Gradle:

dependencies {
    compile 'io.minio:minio:3.0.10'
}

Java API 文档


完整实例

完整示例: Bucket Operations

完整示例: Object Operations

完整示例: Presigned Operations

完整示例: Bucket Policy Operations


需要注意的点

Minio是根据请求头来判断文件类型的,操作时如果有预览需求,一定要注意请求头的设置,比如:
 /**
 * 以流的形式上传对象
 *
 * @param bucketName 存储桶名称
 * @param objectName 对象名称
 * @param stream     流
 * @return 是否成功
 */
public Boolean putObject(String bucketName, String objectName, InputStream stream) {
    try {

        ifBucketExists(bucketName);
        // 创建对象
        minioClient.putObject(bucketName, objectName, stream, stream.available());

        stream.close();
        logger.info("object is uploaded successfully");
        return true;
    } catch (MinioException e) {
        logger.error("存储服务器异常。");
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        logger.error("找不到相应的签名算法。");
        e.printStackTrace();
    } catch (XmlPullParserException e) {
        logger.error("XmlPullParserException");
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        logger.error("不合法的access key或者secret key。");
        e.printStackTrace();
    } catch (IOException e) {
        logger.error("连接异常。");
        e.printStackTrace();
    }
    return false;
}

上面实例中,采用此方法上传的文件,不论图片还是文本,在存储桶中展示均为灰色的文件,这样会导致外联会直接下载文件,从而起不到预览的效果,如下图标红所示:

这是因为Minio的SDK中,默认的请求头为application/octet-stream,源码中也证明了这一点:

if (body != null) {
    requestBody = new RequestBody() {
        public MediaType contentType() {
            MediaType mediaType = null;
            if (contentType != null) {
                mediaType = MediaType.parse(contentType);
            }

            if (mediaType == null) {
                mediaType = MediaType.parse("application/octet-stream");
            }

            return mediaType;
        }

        .
        .
        .
}

将方法改为 如下调用:

try {

minioClient.putObject(bucketName, objectName, stream, stream.available(), "image/jpg");

stream.close();
logger.info("object is uploaded successfully");
return true;
}

这样上传jpg格式的图片,分享的连接就可以预览了。


Minio配置Nginx代理

Minio官方文档有配置nginx代理的说明,但是如果应用到业务当中还是会踩一下坑,在实际应用中,我希望通过配置应用名称的方法达到Java 应用可以连接、分享连接可以下载文件、URL可以直接登录的目的,然后加入如下配置:

location /files {
   proxy_buffering off; //重要!
   proxy_set_header Host $http_host;
   proxy_pass http://localhost:9000;
 }
# 或者
location /minio {
   proxy_buffering off; //重要!
   proxy_set_header Host $http_host;
   proxy_pass http://localhost:9000/minio;
 }

但是这两种配置均不能达到我所希望的效果,第一种直接重定向失败、第二种可以实现网页登录,但是无法实现Java程序连接,连接时报错:

io.minio.errors.InvalidEndpointException: no path allowed in endpoint

意思是路径不被允许,定位到其源码:

if (url != null) {
    if (!"/".equals(url.encodedPath())) {
        throw new InvalidEndpointException(endpoint, "no path allowed in endpoint");
    } else {
        String amzHost = url.host();
        if (amzHost.endsWith(".amazonaws.com") && !amzHost.equals("s3.amazonaws.com")) {
            throw new InvalidEndpointException(endpoint, "for Amazon S3, host should be 's3.amazonaws.com' in endpoint");
        } else {
            Builder urlBuilder = url.newBuilder();
            Scheme scheme = Scheme.HTTP;
            if (secure) {
                scheme = Scheme.HTTPS;
            }

            urlBuilder.scheme(scheme.toString());
            if (port > 0) {
                urlBuilder.port(port);
            }

            this.baseUrl = urlBuilder.build();
            this.accessKey = accessKey;
            this.secretKey = secretKey;
            this.region = region;
        }
    }
}

其中:

if (!"/".equals(url.encodedPath())) {
     throw new InvalidEndpointException(endpoint, "no path allowed in endpoint");
}

猜测Minio的endpoint仅支持到root,也就是/目录下,所以在nginx配置中新加了一个server:

server {
 listen 80; #或者443
 server_name file.example.com;
 location / {
   proxy_buffering off;
   proxy_set_header Host $http_host;
   proxy_pass http://localhost:9000;
 }
}

也就是Minio官方文档上给出的配置。

这样配置对强迫症不太友好,但是为了实现业务职能把Minio的代理单独一个server,配置唯一的二级域名来代理。

关于EOFException

如果你在上传时遇到了EOFException异常,无论是客户端还是服务端,回去检查你的nginx配置,记得一定在映射下加上如下代码:

proxy_buffering off;

最后的话

minio单机版到这里,就告一段落了,由于项目紧急,未能对Minio集群进行研究,待今后有机会再将此文档完善。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • go语言基础10-Goroutine

    吐吐吐吐吐葡萄皮
  • go语言基础11-channel

    吐吐吐吐吐葡萄皮
  • go语言基础5-数组、切片、容器

    吐吐吐吐吐葡萄皮
  • 从0到1学习Oracle--备份与恢复-程国华-专题视频课程

    版权声明:本文为博主原创文章,欢迎扩散,扩散请务必注明出处。 https://blog.csdn.net/robinson_0612/article/d...

    Leshami
  • PowerBI开发与框架参考系列视频与PPT

    近日,Power BI 官方频道开播了一个系列称为《Power BI Adoption Framework》的视频教程,它的目的如下:

    BI佐罗
  • EnterLib PIAB又一个BUG?

    在《这是EnterLib PIAB的BUG吗?》一文中我们讨论了PIAB关于抽象基类的BUG,今天又发现了一个新的问题。问题的起因源于《IoC+AOP的简单实现...

    蒋金楠
  • 通过Service访问应用 (1)

    通过之前的操作,应用部署完成了,我们的Demo网站已经成功启动了,那么如何访问网站呢?

    雪雁-心莱科技
  • 欧洲黑客组织通过已签名的垃圾邮件来实现多阶段恶意软件加载

    在过去的几个月时间里,研究人员观察到了多个新型的恶意垃圾邮件活动。在这些攻击活动中,攻击者使用了一种多阶段恶意软件加载器来传播GootKit银行木马,而这个新出...

    FB客服
  • java虚拟机知识点简要梳理

    首先来看一个java虚拟机的思维导图,下面每个知识点都可以进行展开,本篇只做简要梳理

    lyb-geek
  • 现场:小扎在美国会听证道歉“责任在我”,这些年FB道过的歉

    大数据文摘

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动