MinIo在Ubantu和Java中的整合

news2024/11/16 4:44:38

1.MinIo在Ubantu中的部署

首先准备好一台已经安装好Ubantu系统的服务器

MinIO是一个开源的对象存储服务器,兼容Amazon S3,性能卓越,适合存储非结构化数据,例如照片、视频、日志文件、备份和容器镜像等。

1:更新系统

首先更新你的系统包:

sudo apt update 
​
sudo apt upgrade -y
2:下载和安装MinIO

从MinIO官网下载最新的稳定版本二进制文件:

wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/
3:配置MinIO
  1. 创建MinIO用户: 出于安全考虑,建议以非root用户运行MinIO。

    sudo useradd -r minio-user -s /sbin/nologin
    ​

2.创建目录: 创建MinIO数据和配置文件目录:

sudo mkdir /usr/local/share/minio
sudo mkdir /etc/minio
sudo chown -R minio-user:minio-user /usr/local/share/minio
sudo chown -R minio-user:minio-user /etc/minio

3.设置环境变量: 创建一个文件来存储MinIO环境变量:

sudo nano /etc/default/minio

将以下内容添加到文件中,用你自己的访问密钥和密钥替换YOUR_ACCESS_KEYYOUR_SECRET_KEY

MINIO_VOLUMES="/usr/local/share/minio/"
MINIO_OPTS="--address :9000 --console-address :9090"
MINIO_ACCESS_KEY="YOUR_ACCESS_KEY"
MINIO_SECRET_KEY="YOUR_SECRET_KEY"
  • 9000: MinIO服务端口,即外部访问端口。

  • 9090: MinIO控制台端口,即内部访问端口。

  • YOUR_ACCESS_KEYYOUR_SECRET_KEY: 你的MinIO访问密钥和密钥。

  • /usr/local/share/minio/: MinIO数据目录。

4.创建systemd服务文件: 创建一个systemd服务文件来管理MinIO服务:

sudo nano /etc/systemd/system/minio.service

添加以下内容:

[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
​
[Service]
User=minio-user
Group=minio-user
EnvironmentFile=/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
Restart=always
LimitNOFILE=65536
​
[Install]
WantedBy=multi-user.target

启动MinIO:

sudo systemctl daemon-reload
sudo systemctl start minio
sudo systemctl enable minio

访问MinIO管理页面

管理页面的访问地址为:http://yourIp:9001

API调用的 IP:http://yourIp:9000

注意

ip需要根据实际情况做出修改

2.MinIO快速入门

2.1 MinIO核心概念

下面介绍MinIO中的几个核心概念,这些概念在所有的对象存储服务中也都是通用的。

  • 对象(Object)

    对象是实际的数据单元,例如我们上传的一个图片。

  • 存储桶(Bucket)

    存储桶是用于组织对象的命名空间,类似于文件夹。每个存储桶可以包含多个对象。

  • 端点(Endpoint)

    端点是MinIO服务器的网络地址,用于访问存储桶和对象,例如http://192.168.10.101:9000

    注意:

    9000为MinIO的API的默认端口,前边配置的9001以为管理页面端口。

  • Access Key 和 Secret Key

    Access Key是用于标识和验证访问者身份的唯一标识符,相当于用户名。

    Secret Key是与Access Key关联的密码,用于验证访问者的身份。

2.2 MinIO管理页面操作
  1. 登录

    管理页面的地址为http://192.168.10.101:9001,登录的用户名和密码为部署时在EnvironmentFile文件中配置的如下参数

    MINIO_ROOT_USER=minioadmin
    MINIO_ROOT_PASSWORD=minioadmin
  2. 创建存储桶

  3. 上传图片

    • 找到目标桶

    • 上传图片

  4. 访问图片

    • 图片URL

      由于MinIO提供了HTTP访问功能,所以可以通过浏览器直接访问对象。对象URL为MinIO的Endpoint+对象的存储路径,例如下图中的图片对象的URL为http:192.168.10.101:9000/test/公寓-外观.jpg。

    • 访问权限

      不出意外的话,使用浏览器访问上述URL,会得到如下响应,很显然是没有访问权限。

      <Error>
          <Code>AccessDenied</Code>
          <Message>Access Denied.</Message>
          <Key>A.jpg</Key>
          <BucketName>test</BucketName>
          <Resource>/test/A.jpg</Resource>
          <RequestId>177BC92022FC5684</RequestId>
        <HostId>dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8</HostId>
      </Error>

      若想继续访问图片,需要修改图片所在桶的访问权限,如下图所示

      如上图所示,可选的访问权限共有三个选项,分别是PrivatePublicCustom,具体说明如下

      • Private

        只允许桶的所有者对该桶进行读写。

      • Public

        允许所有人对该桶进行读写。

      • Custom

        自定义访问权限。

      若想将权限设置为只允许所有者写,但允许所有人读,就需要自定义访问权限。自定义访问权限,需要使用一个规定格式的JSON字符串进行描述,具体格式可参考官方文档。

      例如以下JSON字符串表达的含义是:允许(Allow)所有人(*)读取(s3:GetObject)指定桶(test)的所有内容。

      {
        "Statement" : [ {
          "Action" : "s3:GetObject",
          "Effect" : "Allow",
          "Principal" : "*",
          "Resource" : "arn:aws:s3:::test/*"
        } ],
        "Version" : "2012-10-17"
      }

      test桶访问权限设置为Custom,并添加上述内容

    • 重新访问http:192.168.10.101:9000/test/A.jpg,观察是否正常。

2.3 MinIO Java SDK

MinIO提供了多种语言的SDK供开发者使用,本项目需要用到Java SDK,下面通过一个简单案例熟悉一下其基本用法,具体内容可参考官方文档。

  1. 创建一个Maven项目

  2. 引入如下依赖

    <dependency>
        <groupId>io.minio</groupId>
        <artifactId>minio</artifactId>
        <version>8.5.3</version>
    </dependency>
  3. 编写如下内容

    public class App {
        public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
    ​
            try {
                //构造MinIO Client
                MinioClient minioClient = MinioClient.builder()
                        .endpoint("http://192.168.10.101:9000")
                        .credentials("minioadmin", "minioadmin")
                        .build();
    ​
                //创建hello-minio桶
                boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket("hello-minio").build());
                if (!found) {
                    //创建hello-minio桶
                    minioClient.makeBucket(MakeBucketArgs.builder().bucket("hello-minio").build());
                    //设置hello-minio桶的访问权限
                    String policy = """
                            {
                              "Statement" : [ {
                                "Action" : "s3:GetObject",
                                "Effect" : "Allow",
                                "Principal" : "*",
                                "Resource" : "arn:aws:s3:::hello-minio/*"
                              } ],
                              "Version" : "2012-10-17"
                            }""";
                    minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket("hello-minio").config(policy).build());
                } else {
                    System.out.println("Bucket 'hello-minio' already exists.");
                }
    ​
                //上传图片
                minioClient.uploadObject(
                        UploadObjectArgs.builder()
                                .bucket("hello-minio")
                                .object("A.jpg")
                                .filename("D:\\workspace\\hello-minio\\src\\main\\resources\\A.jpg")
                                .build());
                System.out.println("上传成功");
            } catch (MinioException e) {
                System.out.println("Error occurred: " + e);
            }
        }
    }
  4. 运行测试

    运行上述代码,然后查看MinIO管理页面,观察是否上传成功。

3.MioIo在实际项目中的整合应用

3.1图片上传流程

下图展示了新增房间或公寓时,上传图片的流程。

可以看出图片上传接口接收的是图片文件,返回的Minio对象的URL。

3.2 图片上传接口开发

下面为该接口的具体实现

  • 配置Minio Client

    • 引入Minio Maven依赖

      common模块pom.xml文件增加如下内容:

      <dependency>
          <groupId>io.minio</groupId>
          <artifactId>minio</artifactId>
      </dependency>
    • 配置Minio相关参数

      application.yml中配置Minio的endpointaccessKeysecretKeybucketName等参数

      minio:
        endpoint: http://<hostname>:<port>
        access-key: <access-key>
        secret-key: <secret-key>
        bucket-name: <bucket-name>

      注意:上述<hostname><port>等信息需根据实际情况进行修改。

    • common模块中创建com.atguigu.lease.common.minio.MinioProperties,内容如下

      @ConfigurationProperties(prefix = "minio")
      @Data
      public class MinioProperties {
      ​
          private String endpoint;
      ​
          private String accessKey;
      ​
          private String secretKey;
          
          private String bucketName;
      }
    • common模块中创建com.atguigu.lease.common.minio.MinioConfiguration,内容如下

      @Configuration
      @EnableConfigurationProperties(MinioProperties.class)
      public class MinioConfiguration {
      ​
          @Autowired
          private MinioProperties properties;
      ​
          @Bean
          public MinioClient minioClient() {
              return MinioClient.builder().endpoint(properties.getEndpoint()).credentials(properties.getAccessKey(), properties.getSecretKey()).build();
          }
      }
  • 开发图片上传接口

    • 编写Controller层逻辑

      FileUploadController中增加如下内容

      @Tag(name = "文件管理")
      @RequestMapping("/admin/file")
      @RestController
      public class FileUploadController {
      ​
          @Autowired
          private FileService service;
      ​
          @Operation(summary = "上传文件")
          @PostMapping("upload")
          public Result<String> upload(@RequestParam MultipartFile file) {
      ​
              String url = service.upload(file);
              return Result.ok(url);
          }
      }

      说明:MultipartFile是Spring框架中用于处理文件上传的类,它包含了上传文件的信息(如文件名、文件内容等)。

    • 编写Service层逻辑

      • FileService中增加如下内容

        String upload(MultipartFile file);
      • FileServiceImpl中增加如下内容

        @Autowired
        private MinioProperties properties;
        ​
        @Autowired
        private MinioClient client;
        ​
        @Override
        public String upload(MultipartFile file) {
        ​
            try {
                boolean bucketExists = client.bucketExists(BucketExistsArgs.builder().bucket(properties.getBucketName()).build());
                if (!bucketExists) {
                    client.makeBucket(MakeBucketArgs.builder().bucket(properties.getBucketName()).build());
                    client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(properties.getBucketName()).config(createBucketPolicyConfig(properties.getBucketName())).build());
                }
        ​
                String filename = new SimpleDateFormat("yyyyMMdd").format(new Date()) + "/" + UUID.randomUUID() + "-" + file.getOriginalFilename();
                client.putObject(PutObjectArgs.builder().
                        bucket(properties.getBucketName()).
                        object(filename).
                        stream(file.getInputStream(), file.getSize(), -1).
                        contentType(file.getContentType()).build());
        ​
                return String.join("/", properties.getEndpoint(), properties.getBucketName(), filename);
        ​
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
        ​
        private String createBucketPolicyConfig(String bucketName) {
        ​
            return """
                    {
                      "Statement" : [ {
                        "Action" : "s3:GetObject",
                        "Effect" : "Allow",
                        "Principal" : "*",
                        "Resource" : "arn:aws:s3:::%s/*"
                      } ],
                      "Version" : "2012-10-17"
                    }
                    """.formatted(bucketName);
        }

        注意

        上述createBucketPolicyConfig方法的作用是生成用于描述指定bucket访问权限的JSON字符串。最终生成的字符串格式如下,其表示,允许(Allow)所有人(*)获取(s3:GetObject)指定桶(<bucket-name>)的内容。

        {
          "Statement" : [ {
            "Action" : "s3:GetObject",
            "Effect" : "Allow",
            "Principal" : "*",
            "Resource" : "arn:aws:s3:::<bucket-name>/*"
          } ],
          "Version" : "2012-10-17"
        }

        由于公寓、房间的图片为公开信息,所以将其设置为所有人可访问。

        3.3异常处理

        • 问题说明

          上述代码只是对MinioClient方法抛出的各种异常进行了捕获,然后打印了异常信息,目前这种处理逻辑,无论Minio是否发生异常,前端在上传文件时,总是会受到成功的响应信息。可按照以下步骤进行操作,查看具体现象

          关闭虚拟机中的Minio服务

          systemctl stop minio

          启动项目,并上传文件,观察接收的响应信息

        • 问题解决思路

          为保证前端能够接收到正常的错误提示信息,应该将Service方法的异常抛出到Controller方法中,然后在Controller方法中对异常进行捕获并处理。具体操作如下

          Service层代码

          @Override
          public String upload(MultipartFile file) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException{
          ​
              boolean bucketExists = minioClient.bucketExists(
                      BucketExistsArgs.builder()
                              .bucket(properties.getBucketName())
                              .build());
              if (!bucketExists) {
                  minioClient.makeBucket(
                          MakeBucketArgs.builder()
                                  .bucket(properties.getBucketName())
                                  .build());
                  minioClient.setBucketPolicy(
                          SetBucketPolicyArgs.builder()
                                  .bucket(properties.getBucketName())
                                  .config(createBucketPolicyConfig(properties.getBucketName()))
                                  .build());
              }
              String filename = new SimpleDateFormat("yyyyMMdd").format(new Date()) +
                      "/" + UUID.randomUUID() + "-" + file.getOriginalFilename();
              minioClient.putObject(
                      PutObjectArgs.builder()
                              .bucket(properties.getBucketName())
                              .stream(file.getInputStream(), file.getSize(), -1)
                              .object(filename)
                              .contentType(file.getContentType())
                              .build());
          ​
              return String.join("/",properties.getEndpoint(),properties.getBucketName(),filename);
          }

          Controller层代码

          public Result<String> upload(@RequestParam MultipartFile file) {
              try {
                  String url = service.upload(file);
                  return Result.ok(url);
              } catch (Exception e) {
                  e.printStackTrace();
                  return Result.fail();
              }
          }
        • 全局异常处理

          按照上述写法,所有的Controller层方法均需要增加try-catch逻辑,使用Spring MVC提供的全局异常处理功能,可以将所有处理异常的逻辑集中起来,进而统一处理所有异常,使代码更容易维护。

          具体用法如下,详细信息可参考官方文档:

          common模块中创建com.atguigu.lease.common.exception.GlobalExceptionHandler类,内容如下

          @ControllerAdvice
          public class GlobalExceptionHandler {
          ​
              @ExceptionHandler(Exception.class)
              @ResponseBody
              public Result error(Exception e){
                  e.printStackTrace();
                  return Result.fail();
              }
          }

          上述代码中的关键注解的作用如下

          @ControllerAdvice用于声明处理全局Controller方法异常的类

          @ExceptionHandler用于声明处理异常的方法,value属性用于声明该方法处理的异常类型

          @ResponseBody表示将方法的返回值作为HTTP的响应体

          注意:

          全局异常处理功能由SpringMVC提供,因此需要在common模块pom.xml中引入如下依赖

          <!--spring-web-->
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-web</artifactId>
          </dependency>
        • 修改Controller层代码

          由于前文的GlobalExceptionHandler会处理所有Controller方法抛出的异常,因此Controller层就无序关注异常的处理逻辑了,因此Controller层代码可做出如下调整。

          public Result<String> upload(@RequestParam MultipartFile file) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
              String url = service.upload(file);
            return Result.ok(url);
          }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2241268.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式-参考的雷丰阳老师直播课

一般开发中使用的模式为模版模式策略模式组合&#xff0c;模版用来定义骨架&#xff0c;策略用来实现细节。 模版模式 策略模式 与模版模式特别像&#xff0c;模版模式会定义好步骤定义好框架&#xff0c;策略模式定义小细节 入口类 使用模版模式策略模式开发支付 以上使用…

【LeetCode】【算法】53. 最大子数组和

LeetCode 53. 最大子数组和 题目描述 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。子数组是数组中的一个连续部分。 思路 思路&#xff1a;动态规划秒了 具体递推式如…

供应SW6301V单C口多协议升降压移动电源IC

1. 概述 SW6301V 是一款高集成度的单 C 口多协议升降压移动电源 SOC。集成双向升降压控制器&#xff0c;支持 2~6 节 电池串联&#xff0c;提供 100W 功 率 输 入 输 出 &#xff1b; 支 持 C 口 快 充 输入输出 &#xff1b; 支 持UFCS/PPS/PD/SVOOC/VOOC/SCP/FCP/QC/AFC/BC…

C++常用的新特性-->day06

时间间隔duration duration表示一段时间间隔&#xff0c;用来记录时间长度&#xff0c;可以表示几秒、几分钟、几个小时的时间间隔。duration的原型如下 // 定义于头文件 <chrono> template<class Rep,class Period std::ratio<1> > class duration;Rep&…

Cyberchef配合Wireshark提取并解析TCP/FTP流量数据包中的文件

前一篇文章中讲述了如何使用cyberchef提取HTTP/TLS数据包中的文件,详见《Cyberchef配合Wireshark提取并解析HTTP/TLS流量数据包中的文件》,链接这里,本文讲述下如何使用cyberchef提取FTP/TCP数据包中的文件。 FTP 是最为常见的文件传输协议,和HTTP协议不同的是FTP协议传输…

性能面向下一代PCIe Gen 5,G991B322HR、G99L12312HR 安费诺ExtremePort™ Swift连接器支持内部I/O应用

前言 为了在网络设备和服务器上提供更高速度和更小尺寸的解决方案&#xff0c;Amphenol开发了ExtremePort™ Swift连接器&#xff0c;适用于PCIe Gen5 NRZ 32GT/s、UPI 2.0 24GT/s、24Gb/s SAS信号。 G991B322HR G9912312HR G9912322HR G9914312HR G991B312HR G991C312HR G99…

IDEA调整警告级别【IntelliJ IDEA 2024.2.0.1】

文章目录 目前现状鼠标悬停&#xff0c;选择配置筛选 > 取消选择OK效果 目前现状 需要把提示改成只要显示error的5个 鼠标悬停&#xff0c;选择配置 筛选 > 取消选择 OK 效果

【二叉搜素树】——LeetCode二叉树问题集锦:6个实用题目和解题思路

文章目录 计算布尔二叉树的值求根节点到叶节点的数字之和二叉树剪枝验证二叉搜索树二叉搜索树中第K小的元素二叉树的所有路径 计算布尔二叉树的值 解题思路&#xff1a; 这是一个二叉树的布尔评估问题。树的每个节点包含一个值&#xff0c;其中叶子节点值为 0 或 1&#xff0…

windows下QT5.12.11使用MSVC编译器编译mysql驱动并使用详解

1、下载mysql开发库,后面驱动编译的时候需要引用到,下载地址:mysql开发库下载 2、使用everything搜索:msvc-version.conf,用记事本打开,添加:QMAKE_MSC_VER=1909。不然msvc下的mysql源码加载不上。

Isaac Sim+SKRL机器人并行强化学习

目录 Isaac Sim介绍 OmniIssacGymEnvs安装 SKRL安装与测试 基于UR5的机械臂Reach强化学习测评 机器人控制 OMNI GYM环境编写 SKRL运行文件 训练结果与速度对比 结果分析 运行体验与建议 Isaac Sim介绍 Isaac Sim是英伟达出的一款机器人仿真平台&#xff0c;适用于做机…

删库跑路,启动!

起因&#xff1a;这是一个悲伤的故事&#xff0c;在抓logcat时 device待机自动回根目录了&#xff0c;而题主对当前路径的印象还停留在文件夹下&#xff0c;不小心在根目录执行了rm -rf * … 所以&#xff0c;这是个悲伤的故事&#xff0c;东西全没了…device也黑屏了&#xff…

CSS的综合应用例子(网页制作)

这是html的一些最基本内容的代码&#xff1a; <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <t…

SobarQube实现PDF报告导出

文章目录 前言一、插件配置二、使用步骤1.新生成一个Token2.将拷贝的Token加到上文中执行的命令中3.查看报告 三、友情提示总结 前言 这篇博文是承接此文 .Net项目在Windows中使用sonarqube进行代码质量扫描的详细操作配置 描述如何导出PDF报告 众所周知&#xff0c;导出PDF功…

力扣-Mysql-3328-查找每个州的城市 II(中等)

一、题目来源 3328. 查找每个州的城市 II - 力扣&#xff08;LeetCode&#xff09; 二、数据表结构 表&#xff1a;cities ---------------------- | Column Name | Type | ---------------------- | state | varchar | | city | varchar | ----------------…

curl命令提交大json

有个客户需要提交一个4M左右的pdf&#xff0c;接口里传的是pdf字节流base64编码后的字符串。 直接curl -XPOST -d json串 api接口会报 参数过长报错Argument list too long 网上搜了下解决方案把json串放到文本里然后通过json.txt引入参数 这一试不要紧&#xff0c;差点儿导致…

gitlab和jenkins连接

一&#xff1a;jenkins 配置 安装gitlab插件 生成密钥 id_rsa 要上传到jenkins&#xff0c;id_rsa.pub要上传到gitlab cat /root/.ssh/id_rsa 复制查看的内容 可以看到已经成功创建出来了对于gitlab的认证凭据 二&#xff1a;配置gitlab cat /root/.ssh/id_rsa.pub 复制查…

<项目代码>YOLOv8 玉米地杂草识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

Ubuntu+ROS 机械臂拾取和放置

官方链接&#xff1a;https://github.com/skumra/baxter-pnp 1.下载并安装 SDK 依赖项 sudo apt-get install python-wstool python-rosdep 2.创建新的 catkin 工作区 mkdir -p ~/ros_ws/src cd ~/ros_ws/src 3.使用 wstool 下载 rosinstall 文件并将其复制到 Catkin 工作区…

【Linux学习】【Ubuntu入门】1-4 ubuntu终端操作与shell命令1

1.使用快捷键CtrlAltT打开命令终端&#xff0c;或者单击右键点击… 2.常用shell命令 目录信息查看命令&#xff1a;ls ls -a&#xff1a;显示目录所有文件及文件夹&#xff0c;包括隐藏文件&#xff0c;比如以.开头的 ls -l&#xff1a;显示文件的详细信息 ls -al&#xff1…

【含开题报告+文档+PPT+源码】基于springboot的毕业设计选题管理系统

开题报告 毕业设计选题作为高校教学环节中的重要一环&#xff0c;其选题质量和管理效率直接关系到学生毕业设计的质量和毕业要求的达成。然而&#xff0c;传统的选题管理方式往往存在信息不对称、流程繁琐、效率低下等问题&#xff0c;无法满足高校教学管理现代化、信息化的需…