minio - 服务的搭建和使用

minio - 服务的搭建和使用,第1张

目录

Minio Service的搭建

1、Docker方式搭建

2、二进制包安装[不推荐]

3、国内镜像rpm安装

Java客户端 *** 作


曾几何时,之前说的搭建分布式文件存储系统,好像唯一的选择就是 fastDfs,慢慢的发现好像周围的团队和项目都在选择Minio,进入了视野。

Minio与Amazon S3云存储服务兼容,采用Golang实现,服务端支持Windows、Linux、 OS X和FreeBSD等 *** 作系统;客户端支持Java、Python、Javacript、 Golang语言,下面会有基于java的sdk的相关集成和 *** 作。

Minio是Apache License v2.0下发布的对象存储服务器。它与Amazon S3云存储服务兼容。它最适合存储非结构化数据,如照片,视频,日志文件,备份和容器/ VM映像。对象的大小可以从几KB到最大5TB。。。

MinIO中国站点:http://www.minio.org.cn

MinIO中国镜像站:http://dl.minio.org.cn

Minio Service的搭建 1、Docker方式搭建

注意:minio新版本的 API和console端口不能使用同一个,否则会报错:

ERROR Unable to start the server: --console-address cannot be same as --address

docker的安装过程可以参考:Docker的基本概念、环境搭建、常用命令

docker安装 nimio:docker pull minio/minio

启动minio,由于minio会创建动态的端口,并且外网不能进行访问,所以使用以下命令(其中 9000是 web的端口,9001的api的端口,新版本 java sdk不能使用 9000web端口):

docker run minio服务端;-p 9000:9000 --console-address ":9000" 挂载9000端口为web端口; -p 9001:9001 --address ":9001" 挂载9001端口为客户端(如Java客户端)访问的端口;-e 设置9000端口web访问的 账号和密码;-v 挂载数据和配置地址;
docker run -p 9000:9000 -p 9001:9001 --name minio \
-d --restart=always \
-e "MINIO_ACCESS_KEY=mosty" \
-e "MINIO_SECRET_KEY=mosty123456" \
-v /home/data:/data \
-v /home/config:/root/.minio \
minio/minio server --console-address ":9000" --address ":9001" /data

 查看:docker ps -a

使用 docker logs contrain_id 命令查看日志信息:

此时,如果防火墙、或者阿里云或者华为云的安全组规则添加端口,则可以在浏览器使用外网访问,如: http://外网ip:9000/login

登陆后创建 对应的的bucket, 并设置为可以读写权限;就可以客户端就可以访问了;当然客户端也有一点的api创建bucket。。。

2、二进制包安装[不推荐]

说明:下面的官方二进制包拉去会非常慢,也可以使用国内镜像,只是国内镜像已经换成rpm包了

wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
./minio server /data
3、国内镜像rpm安装

国内镜像地址:https://dl.min.io/server/minio/release/linux-amd64/

wget  https://dl.min.io/server/minio/release/linux-amd64/minio-20220326064928.0.0.x86_64.rpm

rpm -ivh minio-20220326064928.0.0.x86_64.rpm

 安装完成可以使用 systemctl status minio 查看状态:

其他rpm包此时就可以使用 systemctl start minio进行启动了,只是此时不能进行启动需要修改 /etc/systemd/system/minio.service文件,将linux的用户名和group修改(可以修改为 root root)

可以修改文件 /etc/default/minio 填写访问的账号密码等,直接将该配置地址也修改为 minio.conf,应该是没有改配置文件的自行创建

touch /etc/default/minio.conf

vi /etc/default/minio.conf

MINIO_VOLUMES="/opt/minio/data"
MINIO_OPTS="--address :9001 --console-address :9000"
MINIO_ACCESS_KEY=kevin
MINIO_SECRET_KEY=kevin123

重新刷新,启动,查看状态:

systemctl daemon-reload

systemctl start minio

systemctl status minio

自行设置Centos防火墙端口,如果是阿里云等请修改安全规则,然后访问 http://ip:9999, 并且我当前的版本使用 docker和rpm安装的界面都不一样(版本不一样)

Java客户端 *** 作

基于spring boot项目,需要引入 minio客户端相关的maven包,


    io.minio
    minio
    8.0.3

下面三个上传图片接口,分别是上传到文件的bucket、上传到图片的bubcket、已经客户端指定桶进行上传(前提是已经创建桶并且开放了权限),上传成功返回可以直接通过外网等访问的URL类似于使用阿里云的OSS,代码和页面样式如下:


import com.mosty.common.base.domain.ResponseResult;
import com.mosty.common.base.exception.Asserts;
import com.mosty.common.core.config.MinIoClientConfig;
import io.minio.BucketExistsArgs;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import io.minio.http.Method;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 *  上传下载服务
 * @author kevin
 * @date 2022/3/7 10:46 AM
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/minio")
@AllArgsConstructor
@Api(tags = "图片上传服务")
@SuppressWarnings("unused")
public class UploadController {

    private final MinioClient minioClient;
    private final MinIoClientConfig minIoClientConfig;


    /**
     * 使用原文件名上传
     * @param file 文件
     * @return 上传结果
     */
    @ResponseBody
    @PostMapping("/image/source/upload")
    @ApiOperation(value = "源文件名上传", httpMethod = "POST", response = Boolean.class)
    public ResponseResult sourceUpload(MultipartFile file) {

        try {
            PutObjectArgs objectArgs = PutObjectArgs.builder().object(file.getOriginalFilename())
                    .bucket(minIoClientConfig.getImageBucket())
                    .contentType(file.getContentType())
                    .stream(file.getInputStream(), file.getSize(), -1).build();

            minioClient.putObject(objectArgs);
            return ResponseResult.success(Boolean.TRUE);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传失败", e);
            return ResponseResult.fail(e.getMessage());
        }
    }

    /**
     * 上传图片
     * @param file 图片
     * @return 图片访问地址
     * @throws Exception 上传结果
     */
    @ResponseBody
    @PostMapping("/image/upload")
    @ApiOperation(value = "前端上传组件使用:上传图片(返回图片的访问地址)", httpMethod = "POST", response = String.class)
    public ResponseResult uploadImage(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.getSize() > 0) {
            return uploadOssWithBucket(file, minIoClientConfig.getImageBucket());
        }
        return ResponseResult.fail("未选择任何文件,上传失败");
    }

    /**
     * 上传文件
     * @param file 文件
     * @return 文件访问地址
     * @throws Exception 异常
     */
    @ResponseBody
    @PostMapping("/file/upload")
    @ApiOperation(value = "前端上传组件使用:上传文件(返回文件的访问地址)", httpMethod = "POST", response = String.class)
    public ResponseResult uploadFile(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.getSize() > 0) {
            return uploadOssWithBucket(file, minIoClientConfig.getFileBucket());
        }
        return ResponseResult.fail("未选择任何文件,上传失败");
    }

    /**
     * 上传文件
     * @param file 文件
     * @param bucketName 桶名称
     * @return 访问地址
     * @throws Exception 异常
     */
    @ResponseBody
    @PostMapping("/{bucketName}/upload")
    @ApiOperation(value = "指定桶上传文件(返回文件的访问地址)", httpMethod = "POST", response = String.class)
    public ResponseResult upload(@RequestParam("file") MultipartFile file,
                                         @PathVariable("bucketName") String bucketName) throws Exception {
        Asserts.check(StringUtils.isEmpty(bucketName), "桶名称不能为空!");
        boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        Asserts.check(!bucketExists, "桶%s不存在!", bucketName);
        if (file.getSize() > 0) {
            return uploadOssWithBucket(file, bucketName);
        }
        return ResponseResult.fail("未选择任何文件,上传失败");
    }

    @NotNull
    private ResponseResult uploadOssWithBucket(MultipartFile file, String bucketName) throws IOException, ErrorResponseException, InsufficientDataException, InternalException, InvalidKeyException, InvalidResponseException, NoSuchAlgorithmException, ServerException, XmlParserException {
        // 原文件名
        String fileName = file.getOriginalFilename();
        if (StringUtils.isEmpty(fileName)) {
            return ResponseResult.fail("文件名不能为空!");
        }
        // 文件类型
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        // 生成新文件名,确保唯一性
        String objectName = UUID.randomUUID() + suffixName;
        // 文件类型
        String fileType = file.getContentType();
        // 使用putObject上传一个文件到存储桶中
        PutObjectArgs build = PutObjectArgs.builder().object(objectName)
                .bucket(bucketName)
                .contentType(file.getContentType())
                .stream(file.getInputStream(), file.getSize(), -1).build();
        minioClient.putObject(build);
        // 得到文件 url
        String url = minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucketName)
                        .object(objectName)
//                                    .expiry(60 * 60 * 24 * 1000)
                        .build());
//        if (!StringUtils.isEmpty(minIoClientConfig.getDownloadEndpoint())) {
//            url = url.replace(minIoClientConfig.getEndpoint(), minIoClientConfig.getDownloadEndpoint());
//        }
        log.info("上传图片 OriginalFilename:{}, objectName:{}, url:{}", file, objectName, url);

        return ResponseResult.success(url);
    }

}

import io.minio.MinioClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 *  minio配置
 * @author kevin
 * @date 2022/3/7 10:41 AM
 * @since 1.0.0
 */
@Data
@Configuration
public class MinIoClientConfig {

    @Value("${minio.endpoint:http://ip:9001}")
    private String endpoint;
    @Value("${minio.downloadEndpoint:http://ip:9000}")
    private String downloadEndpoint;
    @Value("${minio.accessKey:kevin}")
    private String accessKey;
    @Value("${minio.secretKey:kevin123}")
    private String secretKey;
    /** 图片桶名称 */
    @Value("${minio.bucket.image:image}")
    private String imageBucket;
    /** 文件桶名称 */
    @Value("${minio.bucket.file:file}")
    private String fileBucket;


    /**
     * 注入minio 客户端
     * @return
     */
    @Bean
    public MinioClient minioClient() {
        return MinioClient.builder()
                        .endpoint(endpoint)
                        .credentials(accessKey, secretKey)
                        .build();
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/989674.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存