MInIO图片服务器

MInIO

1 基础

1.1 简介

MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、

日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。

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

1.2 纠删玛

Minio使用纠删码erasure code和校验和checksum来保护数据免受硬件故障和无声数据损坏。 即便您丢失一半数量(N/2)的硬盘,您仍然可以恢复数据。

​ 纠删码是一种恢复丢失和损坏数据的数学算法, Minio采用Reed-Solomon code将对象拆分成N/2数据和N/2 奇偶校验块。 这就意味着如果是12块盘,一个

对象会被分成6个数据块、6个奇偶校验块,你可以丢失任意6块盘(不管其是存放的数据块还是奇偶校验块),你仍可以从剩下的盘中的数据进行恢复

​ 纠删码的工作原理和RAID或者复制不同,像RAID6可以在损失两块盘的情况下不丢数据,而Minio纠删码可以在丢失一半的盘的情况下,仍可以保证数据安

全。 而且Minio纠删码是作用在对象级别,可以一次恢复一个对象,而RAID是作用在卷级别,数据恢复时间很长。 Minio对每个对象单独编码,存储服务一经部

署,通常情况下是不需要更换硬盘或者修复。Minio纠删码的设计目标是为了性能和尽可能的使用硬件加速。

# 使用Minio,在12个盘中启动Minio服务。
minio server /data1 /data2 /data3 /data4 /data5 /data6 /data7 /data8 /data9 /data10 /data11 /data12
#  使用Minio Docker镜像,在8块盘中启动Minio服务。
docker run -p 9000:9000 --name minio \
  -v /mnt/data1:/data1 \
  -v /mnt/data2:/data2 \
  -v /mnt/data3:/data3 \
  -v /mnt/data4:/data4 \
  -v /mnt/data5:/data5 \
  -v /mnt/data6:/data6 \
  -v /mnt/data7:/data7 \
  -v /mnt/data8:/data8 \
  minio/minio server /data1 /data2 /data3 /data4 /data5 /data6 /data7 /data8

单点minio需要配置纠删玛磁盘。分布式minio自动引入纠删玛功能

1.3 Minio服务限制

纠删码 (多块硬盘 / 服务)

项目 参数
最大驱动器数量 Unlimited
最小驱动器数量 Unlimited
读仲裁 N / 2
写仲裁 N / 2+1

浏览器访问

项目 参数
Web浏览器上传大小限制 5GB

1.4 MinIO配置指南

MinIO Server config.json (v18) 指南

MinIO server在默认情况下会将所有配置信息存到 ${HOME}/.minio/config.json 文件中。 以下部分提供每个字段的详细说明以及如何自定义它们。一个完整的 config.json 在 这里

配置目录

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

Copyminio server --config-dir /etc/minio /data

证书目录

TLS证书存在${HOME}/.minio/certs目录下,你需要将证书放在该目录下来启用HTTPS 。如果你是一个乐学上进的好青年,这里有一本免费的秘籍传授一你: 如何使用TLS安全的访问minio.

以下是一个带来TLS证书的MinIO server的目录结构。

Copy$ tree ~/.minio
/home/user1/.minio
├── certs
│   ├── CAs
│   ├── private.key
│   └── public.crt
└── config.json

配置参数

版本

参数 类型 描述
version string version决定了配置文件的格式,任何老版本都会在启动时自动迁移到新版本中。 [请勿手动修改]

凭据

参数 类型 描述
credential 对象存储和Web访问的验证凭据。
credential.accessKey string Access key长度最小是5个字符,你可以通过 MINIO_ACCESS_KEY环境变量进行修改
credential.secretKey string Secret key长度最小是8个字符,你可以通过MINIO_SECRET_KEY环境变量进行修改

示例:

export MINIO_ACCESS_KEY=admin
export MINIO_SECRET_KEY=password
minio server /data

区域(Region)

参数 类型 描述
region string region描述的是服务器的物理位置,默认是us-east-1(美国东区1),这也是亚马逊S3的默认区域。你可以通过MINIO_REGION_NAME 环境变量进行修改。如果不了解这块,建议不要随意修改

示例:

export MINIO_REGION_NAME="中国华北一区"
minio server /data

浏览器

参数 类型 描述
browser string 开启或关闭浏览器访问,默认是开启的,你可以通过MINIO_BROWSER环境变量进行修改

示例:

export MINIO_BROWSER=off
minio server /data

通知

参数 类型 描述
notify 通知通过以下方式开启存储桶事件通知,用于lambda计算
notify.amqp 通过AMQP发布MinIO事件
notify.mqtt 通过MQTT发布MinIO事件
notify.elasticsearch 通过Elasticsearch发布MinIO事件
notify.redis 通过Redis发布MinIO事件
notify.nats 通过NATS发布MinIO事件
notify.postgresql 通过PostgreSQL发布MinIO事件
notify.kafka 通过Apache Kafka发布MinIO事件
notify.webhook 通过Webhooks发布MinIO事件

1.5 MinIO多租户

1.5.1 单机部署

要在单台机器上托管多个租户,为每个租户运行一个MinIO server,使用不同的HTTPS端口、配置和数据目录。

示例1:单主机,单磁盘

以下示例在一块磁盘上托管三个租户。

minio --config-dir ~/tenant1 server --address :9001 /data/tenant1
minio --config-dir ~/tenant2 server --address :9002 /data/tenant2
minio --config-dir ~/tenant3 server --address :9003 /data/tenant3

示例2:单主机,多块磁盘 (erasure code)

以下示例在多块磁盘上托管三个租户。

minio --config-dir ~/tenant1 server --address :9001 /disk1/data/tenant1 /disk2/data/tenant1 /disk3/data/tenant1 /disk4/data/tenant1
minio --config-dir ~/tenant2 server --address :9002 /disk1/data/tenant2 /disk2/data/tenant2 /disk3/data/tenant2 /disk4/data/tenant2
minio --config-dir ~/tenant3 server --address :9003 /disk1/data/tenant3 /disk2/data/tenant3 /disk3/data/tenant3 /disk4/data/tenant3

1.5.2 分布式部署

要在分布式环境中托管多个租户,同时运行多个分布式MinIO实例。

示例3 : 多主机,多块磁盘 (erasure code)

以下示例在一个4节点集群中托管三个租户。在4个节点里都执行下列命令:

export MINIO_ACCESS_KEY=
export MINIO_SECRET_KEY=
minio --config-dir ~/tenant1 server --address :9001 http://192.168.10.11/data/tenant1 http://192.168.10.12/data/tenant1 http://192.168.10.13/data/tenant1 http://192.168.10.14/data/tenant1

export MINIO_ACCESS_KEY=
export MINIO_SECRET_KEY=
minio --config-dir ~/tenant2 server --address :9002 http://192.168.10.11/data/tenant2 http://192.168.10.12/data/tenant2 http://192.168.10.13/data/tenant2 http://192.168.10.14/data/tenant2

export MINIO_ACCESS_KEY=
export MINIO_SECRET_KEY=
minio --config-dir ~/tenant3 server --address :9003 http://192.168.10.11/data/tenant3 http://192.168.10.12/data/tenant3 http://192.168.10.13/data/tenant3 http://192.168.10.14/data/tenant3

1.6 磁盘缓存

这里的磁盘缓存功能是指使用缓存磁盘来存储租户常用的一些数据。例如,假设你通过gateway azure设置访问一个对象并下载下来进行缓存,那接下来的请求

都会直接访问缓存磁盘上的对象,直至其过期失效。此功能允许Minio用户:

  • 对象的读取速度性能最佳。
  • 任何对象的首字节时间得到显著改善。

使用

1.6.1 前期条件

安装Minio - Minio快速入门。

1.6.2. 运行Minio缓存

磁盘缓存可以通过修改Minio服务的cache配置来进行开启。配置cache设置需要指定磁盘路径、缓存过期时间(以天为单位)以及使用通配符方式指定的不需要进行缓存的对象。

"cache": {
    "drives": ["/mnt/drive1", "/mnt/drive2", "/mnt/drive3"],
    "expiry": 90,
    "exclude": ["*.pdf","mybucket/*"]
},

缓存设置也可以通过环境变量设置。设置后,环境变量会覆盖任何cache配置中的值。下面示例使用/mnt/drive1, /mnt/drive2/mnt/drive3来做缓存,

90天失效,并且mybucket下的所有对象 和 后缀名为.pdf的对象不做缓存。

export MINIO_CACHE_DRIVES="/mnt/drive1,/mnt/drive2,/mnt/drive3"
export MINIO_CACHE_EXPIRY=90
export MINIO_CACHE_EXCLUDE="*.pdf,mybucket/*"
minio server /export{1...24}

1.6.3. 验证设置是否成功

要验证是否部署成功,你可以通过浏览器来访问刚刚部署的Minio服务。你应该可以看到上传的文件在所有Minio节点上都可以访问。

1.7 MinIO监控指南

MinIO服务器通过端点公开监视数据。监视工具可以从这些端点中选择数据。本文档列出了监视端点和相关文档。

健康检查探针

MinIO服务器具有两个与运行状况检查相关的未经身份验证的端点,一个活动性探针(指示服务器是否工作正常),一个就绪性探针(指示服务器是否由于重负载而未接受连接)。

  • 可在以下位置获得活力探针 /minio/health/live
  • 可在以下位置获得就绪探针 /minio/health/ready

在MinIO healthcheck 指南中阅读有关如何使用这些端点的更多信息。

Prometheus 探测

MinIO服务器在单个端点上公开与Prometheus兼容的数据。默认情况下,对端点进行身份验证。

  • Prometheus 数据可在 /minio/prometheus/metrics

要使用此端点,请设置Prometheus以从该端点抓取数据。在如何使用Prometheus监视MinIO服务器中阅读有关如何配置和使用Prometheus监视MinIO服务器的更多信息。

1.8 设置秘钥

MinIO自定义Access和Secret密钥

方式一 秘钥设置到环境变量中

要覆盖MinIO的自动生成的密钥,您可以将Access和Secret密钥设为环境变量

# 将秘钥添加到环境变量中 -e表示启用解释反斜杠转义,默认为-E:禁用转义
echo -e MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE"\n"MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY >> /etc/profile
# 生效
source /etc/profile

方式二 自定义秘钥

MinIO允许常规字符串作为Access和Secret密钥。

docker run -p 9000:9000 --name minio1 \
  -e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
  -e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
  -v /mnt/data:/data \
  -v /mnt/config:/root/.minio \
  minio/minio server /data

方式三 使用Docker secrets 设置秘钥

要覆盖MinIO的自动生成的密钥,可以把secret和access秘钥创建成Docker secrets. MinIO允许常规字符串作为Access和Secret密钥。

echo "AKIAIOSFODNN7EXAMPLE" | docker secret create access_key -
echo "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" | docker secret create secret_key -

使用docker service创建MinIO服务,并读取Docker secrets。

docker service create --name="minio-service" --secret="access_key" --secret="secret_key" minio/minio server /data

2 单节点安装

2.1 docker下安装单节点MinIO

先安装docker

2.1.1 docker下载 MinIO镜像

docker中运行镜像,镜像删除,存储的数据也就丢失。所以需要将运行的数据挂载到宿主机一个目录中,以防止存储的数据丢失。

要创建具有永久存储的MinIO容器,您需要将本地持久目录从主机操作系统映射到虚拟配置~/.minio 并导出/data目录。

# 1 下载镜像 minio/minio是稳定版   minio/minio:edge 是尝鲜版
docker pull minio/minio

2.1.2 启动

#1 开放防火墙端口
firewall-cmd --zone=public --add-port=9000/tcp --permanent
firewall-cmd --zone=public --add-port=9999/tcp --permanent
systemctl restart firewalld  
firewall-cmd --list-all		
# 2 运行 minio 镜像
docker run  -p 9000:9000 -p 9999:9999  --name minio1 \
  -e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
  -e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
  -v /mnt/data:/data \
  -v /mnt/config:/root/.minio \
  minio/minio server --address '0.0.0.0:9000'  --console-address '0.0.0.0:9999' /data
# 查看
[root@centos1 ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS         PORTS                                       NAMES
5a85b1cc8783   minio/minio   "/usr/bin/docker-ent…"   3 minutes ago   Up 3 minutes   0.0.0.0:9000->9000/tcp, :::9000->9000/tcp   minio1
[root@centos1 ~]# 
  

2.1.3 浏览器访问

浏览器输入 http://192.168.0.201:9999/ 或者9000端口都会映射到9999端口

账号密码是刚才运行时候的 MINIO_ACCESS_KEY 和 MINIO_SECRET_KEY。

能访问说明minio启动成功

2.2 centos 部署单节点minio

2.2.1 下载

http://dl.minio.org.cn/server/minio/release/linux-amd64/minio

并上传到 /usr/local/src 目录下

2.2.3 运行

# 添加防火墙端口

firewall-cmd --zone=public --add-port=9000/tcp --permanent

# 1 给minio添加执行权限
[root@centos9 src]# chmod +x minio
[root@centos9 src]# ll
总用量 240548
-rw-r--r--. 1 root root 185540433 519 16:01 jdk-linux-x64.tar.gz
-rwxr-xr-x. 1 root root  59715584 718 18:50 minio
-rw-r--r--. 1 root root   1061461 714 15:53 nginx-1.20.1.tar.gz
# 2 运行		/data 存储文件目录,可自定义

[root@centos9 src]# ./minio server    /data

No credential environment variables defined. Going with the defaults.
It is strongly recommended to define your own credentials via environment variables MINIO_ROOT_USER and MINIO_ROOT_PASSWORD instead of using default values

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ You are running an older version of MinIO released 4 weeks ago ┃
┃ Update: Run `mc admin update`                                  ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Endpoint: http://192.168.0.209:9000  http://192.168.0.140:9000  http://127.0.0.1:9000     
RootUser: minioadmin 			# 默认账号
RootPass: minioadmin 			# 默认密码

Browser Access:
   http://192.168.0.209:9000  http://192.168.0.140:9000  http://127.0.0.1:9000    

Command-line Access: https://docs.min.io/docs/minio-client-quickstart-guide
   $ mc alias set myminio http://192.168.0.209:9000 minioadmin minioadmin

Object API (Amazon S3 compatible):
   Go:         https://docs.min.io/docs/golang-client-quickstart-guide
   Java:       https://docs.min.io/docs/java-client-quickstart-guide
   Python:     https://docs.min.io/docs/python-client-quickstart-guide
   JavaScript: https://docs.min.io/docs/javascript-client-quickstart-guide
   .NET:       https://docs.min.io/docs/dotnet-client-quickstart-guide
Detected default credentials 'minioadmin:minioadmin', please change the credentials immediately by setting 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD' environment values
IAM initialization complete

# 启动其他参数  
# 1 修改默认端口9000
./minio server  --address 0.0.0.0:80  /data  
# 2 修改公钥(>3) 秘钥(>6) 
export MINIO_ACCESS_KEY=mozhu			
export MINIO_SECRET_KEY=mozhuxianren	
./minio server /data/bucket &
# 3 单点纠删玛  多个存储目录,会将文件分到每个目录存储一部分, 每个存储目录中不是一个完整的文件
./minio server    /home/data1 /home/data2 /home/data3 /home/data4

2.2.4 浏览器访问

账号 和密码 是 刚才启动打印出来的默认账号密码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hFZXOsRV-1635167813679)(MInIO.assets/image-20210718221546276.png)]

# 1 右下角加号,创建bucket   回车就是确定
# 2 左上角创建文件夹
# 3 右下角上传文件
# 4 文件右边有分享图片

2.3 java访问单节点MInio

2.3.1 依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>

        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-lang3artifactId>
        dependency>
        
        <dependency>
            <groupId>io.miniogroupId>
            <artifactId>minioartifactId>
            <version>8.2.2version>
        dependency>
    dependencies>

2.3.2 工具类

package com.mozhu.minioutils;


import io.minio.*;
import io.minio.http.Method;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Component
public class MinioUtils {


    private static final String MINIO_SERVER_URL = "http://192.168.0.209:9000" ;
    private static final String ACCESS_KEY = "minioadmin" ;
    private static final String SECRET_KEY = "minioadmin" ;
    private static final String BUCKET_NAME = "mybucket" ;

    private static MinioClient minioClient;

    // 初始化
    static {

        // Create a minioClient with the MinIO server playground, its access key and secret key.
        minioClient =MinioClient.builder().endpoint(MINIO_SERVER_URL).credentials(ACCESS_KEY, SECRET_KEY).build();

        try {
            // Make BUCKET_NAME bucket if not exist.
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(BUCKET_NAME).build());
            if (!found) {
                // Make a new bucket called 'BUCKET_NAME'.
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(BUCKET_NAME).build() );
            } else {
                System.out.println("Bucket "+ BUCKET_NAME +" already exists.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * @Desirciption:  根据文件本地路径生成随机文件名
     * @Author hgl
     * @Date : 2021-07-19 11:09
     * @Param  originalName 原始名全路径, 需要带后缀
     * @Return
     */
    private static String getRandomFileName ( String originalName ,String prefix ) {
        if (StringUtils.isBlank(originalName)) {
            return null ;
        }

        String subfix = originalName.substring(originalName.lastIndexOf(".") );
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        if ( StringUtils.isNotBlank(prefix) ) {
            return prefix + "/" + uuid + subfix ;
        }
        return   uuid + subfix ;
    }

    /**
     * @Desirciption:  上传文件
     * @Author hgl
     * @Date : 2021-07-19 11:35
     * @Param
     * @Return
     */
    public static String uploadFile ( String originalPath , String prefix ) {
        if ( StringUtils.isBlank( originalPath ) ) {
            return null ;
        }
        // 生成新名字,方式名称冲突
        String fileName = getRandomFileName(originalPath, prefix);
        if ( StringUtils.isBlank( fileName ) ) {
            return null ;
        }
        // 设置前缀

        String objectUrl  = null ;
        try {
            UploadObjectArgs objectArgs = UploadObjectArgs.builder().bucket(BUCKET_NAME).object(fileName).filename(originalPath).build();

            ObjectWriteResponse uploadObject = minioClient.uploadObject(objectArgs);
            // 默认7天 失效  最大是  integer.max的毫秒数 24天
            objectUrl = minioClient.getPresignedObjectUrl( GetPresignedObjectUrlArgs.builder()
                                                                                            .method(Method.GET)
                                                                                            .bucket(BUCKET_NAME)
                                                                                            .object(fileName)
                                                                                            .expiry(24, TimeUnit.DAYS)
                                                                                            .build() );
        } catch (Exception e) {
            e.printStackTrace();
        }
        return objectUrl ;
    }

    /**
     * @Desirciption:  根据文件名称 获取访问链接
     * @Author hgl
     * @Date : 2021-07-19 17:27
     * @Param
     * @Return
     */
    public static String getFilePath ( String fileName ) {
        if ( StringUtils.isBlank(fileName) ) {
            return null ;
        }
        String objectUrl = null;
        try {
            objectUrl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(BUCKET_NAME)
                    .object(fileName)
                    .expiry(7, TimeUnit.DAYS)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return objectUrl ;
    }

    /**
     * @Desirciption:  删除对象
     * @Author hgl
     * @Date : 2021-07-19 17:43
     * @Param
     * @Return
     */
    public static Boolean removeObject ( String objectName ) {
        if ( StringUtils.isBlank( objectName ) ) {
            return false;
        }
        try {
            minioClient.removeObject( RemoveObjectArgs.builder().bucket(BUCKET_NAME).object( objectName ).build());
            return true ;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * @Desirciption:  下载文件
     * @Author hgl
     * @Date : 2021-07-19 18:25
     * @Param objectName 服务器 远程文件名
     * @Param filename   下载到本地文件名
     * @Return
     */
    public static void downloadFile (String objectName , String filename ,HttpServletResponse response) {
        if ( StringUtils.isBlank(objectName)  || response == null) {
            return ;
        }
        // 本地文件名为空,则以远程存储文件名称命名
        if ( StringUtils.isBlank( filename ) ) {
            filename = objectName.substring(objectName.lastIndexOf("/") + 1);
        }
        ServletOutputStream out = null;
        try (InputStream inputStream = minioClient.getObject(
                GetObjectArgs.builder().bucket(BUCKET_NAME).object(objectName).build())) {
            // Read data from stream
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes(),"ISO-8859-1"));
            response.addHeader("Content-Length", "" );
            response.setContentType("application/force-download");
//            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("UTF-8");
            out = response.getOutputStream();
            byte[] content = new byte[1024];
            int length = 0;
            while ((length = inputStream.read(content)) != -1) {
                out.write(content, 0, length);
            }
            out.flush();
        } catch ( Exception e ) {
            e.printStackTrace();
        }finally {
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
}

2.3.3 controller

package com.mozhu.controller;


import com.mozhu.minioutils.MinioUtils;
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 javax.servlet.http.HttpServletResponse;

@RestController
@RequestMapping("/file/")
public class FileController {


    /**
     * @Desirciption:  上传文件
     * @Author hgl
     * @Date : 2021-07-19 17:27
     * @Param  path  用于实际,可以修改为fastdfs 那种参数
     * @Return
     */
    @PostMapping("upload")
    public String uploadFile ( String path , String prefix) {
        String  filePath = MinioUtils.uploadFile(path ,prefix );
        return filePath;
    }



    /**
     * @Desirciption:  获取文件访问地址 默认有效期
     * @Author hgl
     * @Date : 2021-07-19 17:28
     * @Param
     * @Return
     */
    @GetMapping("fileName")
    public String getFIleHttpPath ( String fileName ) {
        String filePath = MinioUtils.getFilePath(fileName);
        return filePath;
    }
    
    /**
     * @Desirciption: 删除
     * @Author hgl
     * @Date : 2021-07-19 22:01
     * @Param 
     * @Return 
     */
    @PostMapping("removeobject")
    public Boolean removeObject ( String fileName ) {
        Boolean object = MinioUtils.removeObject(fileName);
        return object;
    }
    
    /**
     * @Desirciption: 下载
     * @Author hgl
     * @Date : 2021-07-19 22:01
     * @Param 
     * @Return 
     */
    @GetMapping("downloadFile")
    public void downloadFile (String objectName , String filename , HttpServletResponse response ) {
        MinioUtils.downloadFile( objectName ,filename ,response );
    }

}


2.3.4 api说明

上传文件

基本信息

  • 接口URL: localhost:9999/file/upload
  • 请求方式: POST
  • Content-Type: application/x-www-form-urlencoded

请求参数

body参数及说明

参数名 示例值 参数类型 是否必填 参数描述
path D:\Backup\Documents\My Pictures\2050532.jpg string 文件全路径
prefix images string 文件前缀路径,多级用正斜杠隔开 a/b 路径名称规则遵循linux创建文件夹规则

获取文件访问链接

基本信息

  • 接口URL: localhost:9999/file/fileName?fileName=/images/aaa/bbb/ccc/fd9647cde0e643538cd90a3800605578.jpg
  • 请求方式: GET
  • Content-Type: application/x-www-form-urlencoded

请求参数

Query参数及说明

参数名 示例值 参数类型 是否必填 参数描述
fileName /images/aaa/bbb/ccc/fd9647cde0e643538cd90a3800605578.jpg string -

删除

基本信息

  • 接口URL: localhost:9999/file/removeobject
  • 请求方式: POST
  • Content-Type: application/x-www-form-urlencoded

请求参数

body参数及说明

参数名 示例值 参数类型 是否必填 参数描述
fileName images/aaa/bbb/ccc/fd9647cde0e643538cd90a3800605578.jpg string -

下载文件

基本信息

  • 接口URL: localhost:9999/file/downloadFile?objectName=/images/aaa/bbb/ccc/d17bba31b3ad49638842b612f87a5fe8.jpg&filename=123.jpg
  • 请求方式: GET
  • Content-Type: application/x-www-form-urlencoded

请求参数

Query参数及说明

参数名 示例值 参数类型 是否必填 参数描述
objectName /images/aaa/bbb/ccc/d17bba31b3ad49638842b612f87a5fe8.jpg string 远程地址文件 桶后面的的路径
filename 123.jpg string 下载本地文件名

3 分布式运行

3.1 准备

分布式Minio可以让你将多块硬盘(甚至在不同的机器上)组成一个对象存储服务。由于硬盘分布在不同的节点上,分布式Minio避免了单点故障。

在大数据领域,通常的设计理念都是无中心和分布式。Minio分布式模式可以帮助你搭建一个高可用的对象存储服务,你可以使用这些存储设备,而不用考虑其真实物理位置。

数据保护

分布式Minio采用 纠删码来防范多个节点宕机和位衰减bit rot

分布式Minio至少需要4个硬盘,使用分布式Minio自动引入了纠删码功能。

单机Minio服务存在单点故障,相反,如果是一个有N块硬盘的分布式Minio,只要有N/2硬盘在线,你的数据就是安全的。不过你需要至少有N/2+1个硬盘来进行写操作。

例如,一个16节点的Minio集群,每个节点16块硬盘,就算8台服務器宕机,这个集群仍然是可读的,不过你需要9台服務器才能写数据。

注意,只要遵守分布式Minio的限制,你可以组合不同的节点和每个节点几块硬盘。比如,你可以使用2个节点,每个节点4块硬盘,也可以使用4个节点,每个节点两块硬盘,诸如此类。

一致性

Minio在分布式和单机模式下,所有读写操作都严格遵守read-after-write一致性模型。

注意:

  • 分布式Minio里所有的节点需要有同样的access秘钥和secret秘钥,这样这些节点才能建立联接。为了实现这个,你需要在执行minio server命令之前,先将access秘钥和secret秘钥export成环境变量。
  • 分布式Minio使用的磁盘里必须是干净的,里面没有数据。
  • 下面示例里的IP仅供示例参考,你需要改成你真实用到的IP和文件夹路径。
  • 分布式Minio里的节点时间差不能超过3秒,你可以使用NTP 来保证时间一致。
  • 在Windows下运行分布式Minio处于实验阶段,请悠着点使用。

四台服务器 部署 minio

一台服务器安装 nginx

架构如下:

3.2 安装minio

3.2.1 给四台服务器都执行下列命令

# 1 开放防火墙端口
firewall-cmd --zone=public --add-port=9000/tcp --permanent
systemctl restart firewalld
# 2 进入 /usr/local目录
[root@centos8 ~]# cd /usr/local
# 3 上传minio
# 4 给minio 添加执行权限
chmod +x minio
# 5 创建文件夹,修改权限,minio自动创建目录 其他用户没有权限访问
mkdir -p /opt/minio/data
cd /opt/minio/
chmod 777 /opt/minio/data/
# 6 添加环境变量,确保每台机器 accessKey 和 secretKey都 一致
export MINIO_ACCESS_KEY=mozhu			
export MINIO_SECRET_KEY=mozhuxianren
# 7 运行 minio
/usr/local/minio server http://192.168.0.205/opt/minio/data http://192.168.0.206/opt/minio/data \
                        http://192.168.0.207/opt/minio/data http://192.168.0.208/opt/minio/data 
                        

3.2.2 安装nginx

链接 192.168.0.209

#1 进入/usr/local/src
# 2 上传nginx安装包
# 3 安装nginx所需函数库
yum install -y centos-release-scl scl-utils-build
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
scl enable devtoolset-9 bash
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile 

yum install -y pcre pcre-devel

yum install -y zlib zlib-devel

yum install -y openssl openssl-devel
# 4 解压
tar -zxvf nginx-1.20.1.tar.gz 
# 5 进入目录 编译配置 默认安装在  /usr/local/ 下
cd nginx-1.20.1
./configure
make
make install
# 6 进入nginx 配置目录
 cd /usr/local/nginx/conf/
# 7 修改配置文件
upstream backend {
		192.168.0.205:9000 ;
		192.168.0.206:9000 ;
		192.168.0.207:9000 ;
		192.168.0.208:9000 ;
	}
    server {
        listen       9000;
        server_name  localhost;
        location /{
			proxy_pass http://backend    ;
			proxy_set_header Host $http_host;
	    }
    }
# 8 检查nginx 配置文件语法
[root@centos9 conf]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@centos9 conf]# 
# 9 运行nginx
[root@centos9 conf]# /usr/local/nginx/sbin/nginx


3.3.3 Java测试

用上面的单节点java代码测试

初始化修改一下常量

private static final String MINIO_SERVER_URL = "http://192.168.0.209:9000" ;
private static final String ACCESS_KEY = "mozhu" ;
private static final String SECRET_KEY = "mozhuxianren" ;

上传图片成功,浏览器访问返回图片链接成功。

你可能感兴趣的:(图片服务器,java)