SpringBoot+Minio搭建不再爆肝秃头的分布式文件服务器

【minio】linux集群部署minio,springboot整合教程,解决Response code: 502, Content-Type: null, body:问题 linux部署minio,java sdk调用操作minio教程 阅读详情

前言

1)、有人一定会问,为什么不用FastDFS?众所周知,FastDFS的原生安装非常复杂,有过安装经验的人大体都明白,虽然可以利用别人做好的docker直接安装,但真正使用过程中也可能出现许多莫名其妙的问题;
2)、还有人会问,为什么不用oss或其他现有云产品?道理很简单,你不能保证自己所在的公司拥有的项目一定会上云,据我个人了解,大部分公司要么依托于甲方使用内网服务器,要么是公司自己内部搭建的,比如我公司就是依托于医院自己的服务器,所有部署以安全为首,只能自己搭建内部文件服务器;
3)、Minio是GO语言开发的,性能很好,安装简单,可分布式存储海量图片、音频、视频等文件,且拥有自己的管理后台界面,十分友好。
4)、我有个习惯,每年会观察流量大的培训机构会新增什么技术去除什么技术,虽然Minio出来也有些时日了,但这两年陆续有知名机构的讲师开始引入Minio了,意味着这个产品的接受度正在升高,随着培训机构培养的人员扩散到各个IT公司,接受度只会越来越高。
所以,此时不了解更待何时~

minio官网地址: docs.min.io/docs/minio-…
minio中文网地址: docs.minio.org.cn/docs/

特别说明:大部分内容直接看中文网即可,但下载minio时,最好看官网,因为minio版本更新非常快,经常会出现资源文件更换目录的情况,同时中文网的地址可能会失效,导致下载失败。

搭建Minio

分为下载、安装、启动、访问、自定义启动脚本及设置永久访问链接等几步操作。

1. 下载minio

1)、手工下载:docs.min.io/docs/minio-…

找到这个位置,下载自己需要的版本,我这里使用Linux,所以下载第一个就行。

2)、远程拉取
  创建自己的minio目录
  远程拉取: wget http://dl.minio.org.cn/server/minio/release/darwin-amd64/minio[

2. 安装minio

1)、给minio二进制文件赋权限,否则无法执行:chmod +x minio
  2)、在二进制文件所在目录执行 ./minio ,成功后可看到最下面的版本号,我这里安装的是当前最新版。

3. 启动minio

1)、在minio安装目录新建data目录,用来存放minio的数据:mkdir data ;

2)、在后台进程启动minio: ./minio server /data/minio/data > /data/minio/minio.log 2>&1 &
    查看后台运行日志: tail -f minio.log

特别说明: 这里日志可以看出来,新版的minio和老版是有区别的,这里API后面的地址是9000端口,console也就是控制台地址的端口是33587,而且最后一句WARNING有提示,控制台端口是动态生成的,请使用命令选择一个静态端口,意思就是如果重启了,那么这个控制台的端口又会发生改变,需要自己设置一个固定不变的静态端口,具体的设置方法可以按照提示的命令设置。
命令如下:(注意重启时要执行 kill -9 [进程号] 把之前后台进程启动的minio杀掉)

# 指定后台端口为9999
./minio server --console-address 0.0.0.0:9999 /data/minio/data > /data/minio/minio.log 2>&1 &

4. 访问minio

设置固定的静态端口后,日志提示的访问地址是 http://127.0.0.1:9999 ,这里我们就替换成自己服务器的ip地址即可,我这里用的是腾讯云服务器。
  访问地址:http://42.193.14.144:9999
  效果如下,和老版的界面也不一样了:
  默认账号密码: minioadmin minioadmin

5. 自定义脚本启动minio

1)、新建一个shell脚本,把启动时需要设置的命令放进来即可。这里新增了设置账号密码的命令,不再用之前的默认账号密码minioadmin。
  新建shell脚本:vim minio-start.sh

# 设置账号密码
export MINIO_ACCESS_KEY=root
export MINIO_SECRET_KEY=123456

# 后台进程启动minio
./minio server --console-address 0.0.0.0:9999 /data/minio/data > /data/minio/minio.log 2>&1 &

2)、给这个脚本赋予执行权限:chmod +x minio-start.sh
  3)、执行脚本启动minio:./minio-start.sh

最终效果和上面一样!

6. 使用minio

进入后台后便可以简单使用minio上传文件、预览、分享URL等来尝试minio带来的美好。 许多配置使用默认的就好,不明白的就多点点很快就会了,唯一要明白的是Bucket概念,因为调用minio的API时经常会用到它,简单点就可以理解为存放鸡蛋的篮子(存放文件的目录)。

PS: 刚开始使用的同学可能会习惯点击文件右侧几个按钮中的share按钮copy后台生成的文件链接,然后粘贴到浏览器打开,基本上都会遭遇打不开的情况,因为你仔细看链接就发现,这个链接地址的ip端口是错误的,这是一个误区,我们一般使用minio会通过mc客户端来执行命令进行一些配置,达到永久访问文件及直接下载文件的效果。

7. 设置永久访问链接

1)、安装mc客户端
  可以参考官网,写的很详细:docs.min.io/docs/minio-…
  也可以参考中文网: docs.minio.org.cn/docs/master…
  当你打开文档读一会儿后,你会发现写的很棒,但是看不懂。没关系,有许多踩过坑的人已经把障碍扫清了。

安装MC客户端: wget https://dl.min.io/client/mc/release/linux-amd64/mc

这里就印证了我前面讲的,安装minio相关文件最好看官网,这里的中文网地址无法下载 了,所以无法安装成功。

官网mc安装地址:

中文网mc安装地址:(这个我使用时已经失效了)

同样的,要给mc执行文件赋予权限,否则会提示权限不足的错误。
  chmod +x mc

设置永久访问链接,这里官网和中文网都讲的不清楚,个人认为这里就是设置了一个可访问的前缀地址,方便之后开放桶权限后能直接访问到图片,方便理解你可以想象为nginx做代理。

设置配置名称为minio,设置访问前缀为http://42.193.14.144 ,这是前面说的我的腾讯云服务器地址,端口设为9000,当然也可以设为别的,我这里设为9000是因为腾讯云安全组的规则已经存在9000端口,我不需要重新添加规则了。这里的root和123456就是前面自定义启动脚本设置的账号密码,你改成自己的就好。其他都不需要改。

./mc config host add minio http://42.193.14.144:9000 root 123456 --api S3v4

特别说明:切记,这里设置端口,如果用的是本地虚拟机,要么关闭防火墙,要么就打开你设定的这个端口;如果用的是和我一样的云服务器,不管有没有打开防火墙,都要在云服务器后台管理中添加规则开放这个端口,否则你依然打不开文件。

设置某个桶(即文件目录)中的文件可直接下载的权限:./mc policy set download minio/hospitalimages

这里的hospitalimages就是我自己建的存放互联网医院文件的桶了,记得一定要加上前面的minio,是上一步命令设定的配置名。

执行命令后,这个桶下面的文件就可以直接访问到了。
  设置永久访问链接和下载权限的命令执行完后,最终效果如下:
可通过 http://服务器ip:端口/桶名称/文件名称 直接访问到了!

SpringBoot整合Minio

特别说明:minio引入不同版本依赖使用过程是有较大区别的,比如7和8就区别很大,本人也踩过不少坑,搜过不少资料,虽然7版本算是用上了,但目前版本较新,就使用8版本,8的坑也很多,后来在某网站的风间影月老师那里终于找到了能使用的方案,也已经用在了公司的项目中,在这里直接分享给大家。

1. 引入依赖

<!-- MinIO -->
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.2.1</version>
</dependency>

2. MinioUtils工具类

import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

/**
 * MinIO工具类
 *
 * @author guoj
 * @date 2021/12/14 19:30
 */
@Slf4j
public class MinIOUtils {

    private static MinioClient minioClient;

    private static String endpoint;
    private static String bucketName;
    private static String accessKey;
    private static String secretKey;
    private static Integer imgSize;
    private static Integer fileSize;

    private static final String SEPARATOR = "/";

    public MinIOUtils() {
    }

    public MinIOUtils(String endpoint, String bucketName, String accessKey, String secretKey, Integer imgSize, Integer fileSize) {
        MinIOUtils.endpoint = endpoint;
        MinIOUtils.bucketName = bucketName;
        MinIOUtils.accessKey = accessKey;
        MinIOUtils.secretKey = secretKey;
        MinIOUtils.imgSize = imgSize;
        MinIOUtils.fileSize = fileSize;
        createMinioClient();
    }

    /**
     * 创建基于Java端的MinioClient
     */
    public void createMinioClient() {
        try {
            if (null == minioClient) {
                log.info("开始创建 MinioClient...");
                minioClient = MinioClient
                                .builder()
                                .endpoint(endpoint)
                                .credentials(accessKey, secretKey)
                                .build();
                createBucket(bucketName);
                log.info("创建完毕 MinioClient...");
            }
        } catch (Exception e) {
            log.error("[Minio工具类]>>>> MinIO服务器异常:", e);
        }
    }

    /**
     * 获取上传文件前缀路径
     * @return
     */
    public static String getBasisUrl() {
        return endpoint + SEPARATOR + bucketName + SEPARATOR;
    }

    /******************************  Operate Bucket Start  ******************************/

    /**
     * 启动SpringBoot容器的时候初始化Bucket
     * 如果没有Bucket则创建
     * @throws Exception
     */
    private static void createBucket(String bucketName) throws Exception {
        if (!bucketExists(bucketName)) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }
    }

    /**
     *  判断Bucket是否存在,true:存在,false:不存在
     * @return
     * @throws Exception
     */
    public static boolean bucketExists(String bucketName) throws Exception {
        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    }

    /**
     * 获得Bucket的策略
     * @param bucketName
     * @return
     * @throws Exception
     */
    public static String getBucketPolicy(String bucketName) throws Exception {
        return minioClient
                                .getBucketPolicy(
                                        GetBucketPolicyArgs
                                                .builder()
                                                .bucket(bucketName)
                                                .build()
                                );
    }

    /**
     * 获得所有Bucket列表
     * @return
     * @throws Exception
     */
    public static List<Bucket> getAllBuckets() throws Exception {
        return minioClient.listBuckets();
    }

    /**
     * 根据bucketName获取其相关信息
     * @param bucketName
     * @return
     * @throws Exception
     */
    public static Optional<Bucket> getBucket(String bucketName) throws Exception {
        return getAllBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
    }

    /**
     * 根据bucketName删除Bucket,true:删除成功; false:删除失败,文件或已不存在
     * @param bucketName
     * @throws Exception
     */
    public static void removeBucket(String bucketName) throws Exception {
        minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
    }

    /******************************  Operate Bucket End  ******************************/

    /******************************  Operate Files Start  ******************************/

    /**
     * 判断文件是否存在
     * @param bucketName 存储桶
     * @param objectName 文件名
     * @return
     */
    public static boolean isObjectExist(String bucketName, String objectName) {
        boolean exist = true;
        try {
            minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (Exception e) {
            log.error("[Minio工具类]>>>> 判断文件是否存在, 异常:", e);
            exist = false;
        }
        return exist;
    }

    /**
     * 判断文件夹是否存在
     * @param bucketName 存储桶
     * @param objectName 文件夹名称
     * @return
     */
    public static boolean isFolderExist(String bucketName, String objectName) {
        boolean exist = false;
        try {
            Iterable<Result<Item>> results = minioClient.listObjects(
                    ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());
            for (Result<Item> result : results) {
                Item item = result.get();
                if (item.isDir() && objectName.equals(item.objectName())) {
                    exist = true;
                }
            }
        } catch (Exception e) {
            log.error("[Minio工具类]>>>> 判断文件夹是否存在,异常:", e);
            exist = false;
        }
        return exist;
    }

    /**
     * 根据文件前置查询文件
     * @param bucketName 存储桶
     * @param prefix 前缀
     * @param recursive 是否使用递归查询
     * @return MinioItem 列表
     * @throws Exception
     */
    public static List<Item> getAllObjectsByPrefix(String bucketName,
                                                   String prefix,
                                                   boolean recursive) throws Exception {
        List<Item> list = new ArrayList<>();
        Iterable<Result<Item>> objectsIterator = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
        if (objectsIterator != null) {
            for (Result<Item> o : objectsIterator) {
                Item item = o.get();
                list.add(item);
            }
        }
        return list;
    }

    /**
     * 获取文件流
     * @param bucketName 存储桶
     * @param objectName 文件名
     * @return 二进制流
     */
    public static InputStream getObject(String bucketName, String objectName) throws Exception {
        return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    /**
     * 断点下载
     * @param bucketName 存储桶
     * @param objectName 文件名称
     * @param offset 起始字节的位置
     * @param length 要读取的长度
     * @return 二进制流
     */
    public InputStream getObject(String bucketName, String objectName, long offset, long length)throws Exception {
        return minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .offset(offset)
                        .length(length)
                        .build());
    }

    /**
     * 获取路径下文件列表
     * @param bucketName 存储桶
     * @param prefix 文件名称
     * @param recursive 是否递归查找,false:模拟文件夹结构查找
     * @return 二进制流
     */
    public static Iterable<Result<Item>> listObjects(String bucketName, String prefix,
                                                     boolean recursive) {
        return minioClient.listObjects(
                ListObjectsArgs.builder()
                        .bucket(bucketName)
                        .prefix(prefix)
                        .recursive(recursive)
                        .build());
    }

    /**
     * 使用MultipartFile进行文件上传
     * @param bucketName 存储桶
     * @param file 文件名
     * @param objectName 对象名
     * @param contentType 类型
     * @return
     * @throws Exception
     */
    public static ObjectWriteResponse uploadFile(String bucketName, MultipartFile file,
                                                String objectName, String contentType) throws Exception {
        InputStream inputStream = file.getInputStream();
        return minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .contentType(contentType)
                        .stream(inputStream, inputStream.available(), -1)
                        .build());
    }

    /**
     * 上传本地文件
     * @param bucketName 存储桶
     * @param objectName 对象名称
     * @param fileName 本地文件路径
     */
    public static ObjectWriteResponse uploadFile(String bucketName, String objectName,
                                                String fileName) throws Exception {
        return minioClient.uploadObject(
                UploadObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .filename(fileName)
                        .build());
    }

    /**
     * 通过流上传文件
     *
     * @param bucketName 存储桶
     * @param objectName 文件对象
     * @param inputStream 文件流
     */
    public static ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream) throws Exception {
        return minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .stream(inputStream, inputStream.available(), -1)
                        .build());
    }

    /**
     * 创建文件夹或目录
     * @param bucketName 存储桶
     * @param objectName 目录路径
     */
    public static ObjectWriteResponse createDir(String bucketName, String objectName) throws Exception {
        return minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .stream(new ByteArrayInputStream(new byte[]{}), 0, -1)
                        .build());
    }

    /**
     * 获取文件信息, 如果抛出异常则说明文件不存在
     *
     * @param bucketName 存储桶
     * @param objectName 文件名称
     */
    public static String getFileStatusInfo(String bucketName, String objectName) throws Exception {
        return minioClient.statObject(
                StatObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build()).toString();
    }

    /**
     * 拷贝文件
     *
     * @param bucketName 存储桶
     * @param objectName 文件名
     * @param srcBucketName 目标存储桶
     * @param srcObjectName 目标文件名
     */
    public static ObjectWriteResponse copyFile(String bucketName, String objectName,
                                                 String srcBucketName, String srcObjectName) throws Exception {
        return minioClient.copyObject(
                CopyObjectArgs.builder()
                        .source(CopySource.builder().bucket(bucketName).object(objectName).build())
                        .bucket(srcBucketName)
                        .object(srcObjectName)
                        .build());
    }

    /**
     * 删除文件
     * @param bucketName 存储桶
     * @param objectName 文件名称
     */
    public static void removeFile(String bucketName, String objectName) throws Exception {
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build());
    }

    /**
     * 批量删除文件
     * @param bucketName 存储桶
     * @param keys 需要删除的文件列表
     * @return
     */
    public static void removeFiles(String bucketName, List<String> keys) {
        List<DeleteObject> objects = new LinkedList<>();
        keys.forEach(s -> {
            objects.add(new DeleteObject(s));
            try {
                removeFile(bucketName, s);
            } catch (Exception e) {
                log.error("[Minio工具类]>>>> 批量删除文件,异常:", e);
            }
        });
    }

    /**
     * 获取文件外链
     * @param bucketName 存储桶
     * @param objectName 文件名
     * @param expires 过期时间 <=7 秒 (外链有效时间(单位:秒))
     * @return url
     * @throws Exception
     */
    public static String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) throws Exception {
        GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().expiry(expires).bucket(bucketName).object(objectName).build();
        return minioClient.getPresignedObjectUrl(args);
    }

    /**
     * 获得文件外链
     * @param bucketName
     * @param objectName
     * @return url
     * @throws Exception
     */
    public static String getPresignedObjectUrl(String bucketName, String objectName) throws Exception {
        GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
                                                                    .bucket(bucketName)
                                                                    .object(objectName)
                                                                    .method(Method.GET).build();
        return minioClient.getPresignedObjectUrl(args);
    }

    /**
     * 将URLDecoder编码转成UTF8
     * @param str
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String getUtf8ByURLDecoder(String str) throws UnsupportedEncodingException {
        String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
        return URLDecoder.decode(url, "UTF-8");
    }

    /******************************  Operate Files End  ******************************/

}

总结

这样其实就完成了整合,是不是So Easy?咔咔,在需要用到的地方通过MinioUtils.xxx()方法调用即可,比如我在公司项目中用到的就是MinioUtils.getPresignedObjectUrl()这个获取文件外链的方法,因为大多数时候不需要你对文件本身进行修改删除操作,正常来讲只会用到上传和查询文件的操作,在设计上许多产品老师也会规避这种风险问题。另外,工具类中传递的endpoint、bucketName、accessKey、ecretKey等参数,都是在minio后台可以拿到的,没有的话也可以自己设置。

【SpringBoot】SpringBoot 集成 Minio、OSS MinIO 是一款基于 Go 语言发开的高性能、分布式的对象存储系统。简单来说:就是可以存视频、图片 等。可以创建一个 bucket。 阅读详情

相关推荐

从ADS到Origin:高效绘制负载牵引Smith圆图的完整指南

本文提供了一份从ADS导出负载牵引数据并在Origin中绘制专业Smith圆图的完整指南。详细介绍了数据导出、导入、关键的数据解释步骤,以及高效处理多组曲线的技巧,帮助射频工程师快速生成用于报告和论文的出版级图表。

tgb3456789的博客 1137

minio的安装和springboot集成minio

minio的安装和springboot集成minio

qq_47614329的博客 5456

axi时序图_(AXI)握手协议(pvld/prdy或者valid-ready)中ready打拍技巧

内容提要ready打拍的问题用FIFO的思路去解决用Buffer的思路去解决问题提出:ready时序如何优化?在valid/ready 握手协议中,valid 与 data的时序优化比较容易理解,(不熟悉valid/ready协议或者valid打拍方法的)大家可以参考上次推送(握手协议(pvld/prdy或者valid-ready或AXI)中Valid及data打拍技巧)。 但是有时候,关键路径是...

weixin_29763641的博客 3323

Minio工具类 - Java

依赖 <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>${minio.version}</version> </dependency> 项目启动,创建bean package com.mgmiot.dlp.file.filev2.config; import com.mg

流氓兔的博客 3万+

ENVI遥感数字图像处理方法(一)

文章目录1.查看图像的空间分布特征(一)生成灰度图像(二)生成假彩色图像(三)连接不同视图的影像2.查看图像的像元灰度值3.统计并查看图像直方图 1.查看图像的空间分布特征 在打开一幅遥感影像时,有两个文件,我们要选择数据文件来打开。 打开过后,点击Data Manager,查看该影像的波段 该影像共有6个波段 (一)生成灰度图像 步骤如下: (二)生成假彩色图像 先生成一个一般的假彩色图像: 再生成一个标准假彩色图像,将其存放在一个新的视图中: 标准假彩色图像波段构成为:近红外、红光波段、绿

江昊东的博客 5万+

基于E310的纯逻辑代码实现AD9361射频收发

基于微相科技的E310平台实现AD9361的射频收发功能。采用纯逻辑控制的方式,不需要PS参与。实现了用VIO控制收发使能,发射功率,收发频率,数据接口时序控制,接收增益,BIST测试等功能。

xiaomingzi55的博客 2331

MinIO的安装部署及Spring Boot整合使用MinIO进行文件读写访问

项目中用到图片和文件的存储及展示,之前部署在阿里云的OSS,因为贫穷问题,从OSS换成自己部署一套文件服务器。在FastDFS和MinIO中选型了后者,开箱即用,比较方便。这里记录并分享下安装部署及使用的方案。

laolitou_1024的博客 1716

实战篇(一):从零构建领域知识图谱——基于Protege的本体建模与知识表示

本文详细介绍了如何从零构建领域知识图谱,重点讲解了基于Protege的本体建模与知识表示方法。通过游戏和电影领域的实战案例,展示了类层次结构设计、属性关系定义、推理验证等关键步骤,帮助读者掌握知识图谱构建的核心技术。

weixin_42613501的博客 481

minio单机、集群搭建、Spring Boot集成,详细步骤

1.下载rpm包下载地址:https://dl.min.io/server/minio/release/linux-amd64/ 2.安装 修改 /etc/systemd/system/minio.service文件 创建配置文件并编辑: 安装完成,启动,并查看状态: 3.浏览器访问:http://ip:9000若无法访问则关闭防火墙或打开端口 使用刚刚配置的账户信息登陆即可。192.168.14.131192.168.14.133192.168.14.134192.168.14.13

z69183787的专栏 5239

【WorkBuddy专栏32】从「分文件夹」到「组队打仗」——WorkBuddy v5.0项目模式深度拆解

【WorkBuddy专栏32】从「分文件夹」到「组队打仗」——WorkBuddy v5.0项目模式深度拆解

AI人人懂 297

最新腾讯手游游戏appid列表及urlScheme一览 urlscheme查询

[全网独家] 2024最新腾讯游戏appid列表及urlScheme一览 手游包含王者荣耀QQ飞车我的世界PUBG吃鸡和平精英金铲铲之战三角洲行动QQ炫舞拳皇98OL欢乐斗地主 元梦之星使命召唤等

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 2万+

SpringBoot+MinIO实现minio部署和使用

功能完善:Minio支持云原生,能与Kubernetes、Docker、Swarm编排系统良好对接,实现灵活部署。简单、可靠:Minio采用简单可靠的集群方案,摒弃复杂的大规模的集群调度管理,减少风险与性能瓶颈,聚焦产品的核心功能,打造高可用的集群、灵活的扩展能力以及超过的性能。Minio是一个go编写基于Apache License v2.0开源协议的对象存储系统,是为海量数据存储、人工智能、大数据分析而设计,它完全兼容Amazon S3接口,十分符合存储大容量的非结构化数据从几十kb到最大5T不等。

qq_39990869的博客 7241

检测头篇 | 手把手教你如何去更换YOLOv8的检测头为ASFF_Detect

自适应空间特征融合(ASFF)的主要原理旨在解决单次检测器中不同尺度特征的不一致性问题。具体来说,ASFF通过动态调整来自不同尺度特征金字塔层的特征贡献,确保每个检测对象的特征表示是一致且最优的。本文所做出的改进是将YOLOv8的检测头更换为ASFF_Detect。🌈

小哥谈 2497

SpringBoot+Minio搭建不再秃头的分布式文件服务器

有人一定会问,为什么不用FastDFS?众所周知,FastDFS的原生安装非常复杂,有过安装经验的人大体都明白,虽然可以利用别人做好的docker直接安装,但真正使用过程中也可能出现许多莫名其妙的问题……

xiangyangsanren的专栏 2098

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Sprinboot整合minio,实现文件的上下传功能

Minio是一款高性能的对象存储服务器,它兼容Amazon S3 API。它的设计目的是为了提供云存储服务的性能和可扩展性,同时还保持着本地存储的简单性和易用性。Minio可以在Linux、MacOS和Windows等操作系统上运行,它可以通过命令行界面或RESTful API进行管理。

weixin_42682398的博客 504

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

SpringBoot集成MinIO分布式文件系统

首先搭建MinIO的集群,集群搭建参考《》

Java后端技术栈 1564

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

docker+minio+springboot 图片上传下载

docker+minio+springboot 实现图片上传下载

weixin_42510445的博客 735

使用Docker Compose部署Minio

使用Docker Compose部署Minio 配置文件原地址:https://raw.githubusercontent.com/minio/minio/master/docs/orchestration/docker-compose/docker-compose.yaml version: '3.7' # starts 4 docker containers running minio ...

ja.rome 5299

minio中的安装启动地址问题

附加一个启动命令:nohup ./minio server --address 0.0.0.0:9000 --console-address 0.0.0.0:9999 /usr/src/local/minio/data &参数:用于指定MinIO服务器监听的S3 API访问地址。控制台是MinIO的管理界面,提供了用户友好的界面来管理存储桶、对象和访问权限等。参数用于MinIO服务器控制台访问。参数,您可以指定MinIO服务器控制台的IP地址和端口。参数,您可以指定MinIO服务器监听的IP地址和端口。

qq_63922888的博客 7572

【分布式云储存】Springboot微服务接入MinIO实现文件服务

Springboot微服务接入MinIO实现文件服务较为简单,我们只要按照官方文档引入依赖调用即可。值得注意的是我们根据需求选择接入ssl兼容方案和静态资源预览功能。当然,minio的private\custom\public可以完全实现我们各种需求,可以完全替代市场上付费和笨重的分布式服务。

勤于笔记,成于点滴。 3128

学习笔记—文件管理—minio,安装、集群部署及与Springboot结合

做一个简单的总结,Spring Boot 集成 MinIO 的好处在于它提供了一个轻量级、兼容 S3 的对象存储解决方案,支持高可用、分布式存储,以及精细的访问控制。MinIO 是一个高性能的对象存储系统,专为私有云和混合云环境设计,支持存储海量的非结构化数据,如图片、视频、备份、日志文件等。通过将minio和springboot进行集成,有利于实现简便的对象存储操作,一些常见的场景比如多媒体管理的场景、日志和备份管理的场景、文件共享平台等等。此外,在分布式集群中,MinIO 会自动处理数据的分片和复制。

qq_34257208的博客 2570

docker 部署minio,分享地址为docker内ip地址问题

新版本minio,分享地址带了ip,如果使用docker部署,分享地址内的ip则是docker内的ip,复制地址替换为宿主机地址访问会报错。解决方案:启动时增加环境变量:MINIO_SERVER_URL:http://宿主机ip:宿主机映射的9000端口改环境变量值为:宿主机ip和宿主机的映射端口...

u010207995的博客 7737

docker部署minio分享图片链接ip问题

部署脚本 http://192.168.67.199:9001/login 上传一个图片并生成分享链接 我们把它换成主机ip,发现报错了 处理方法:把ip换做外网ip,并去掉验证信息 我生成分享链接的目的是把minio当作一个图床服务器,后来发现在html中使用img标签中使用 即可看到图片 --------------------- 作者:晓倾城 来源:优快云 原文:https://blog.youkuaiyun.com/qq_40850266/article/details

jiaoqi6132的博客 5875

MinIO 如何设置永久分享链接

MinIO 可以被当做一个轻量级的云盘或文件数据库,默认存储在桶里的文件只能分享7天,但是当我想把它当做文件数据库时,就需要将文件分享设置为永久,那么该如何做呢? 官方文档在 MinIO Admin 中有对桶的策略进行设置: 将桶设置为可永久分享: bucket_policy = { 'Version': '2012-10-17', 'Statement': [ { 'Effect': 'Allow', 'Principal'

极客点儿 9813

Spring Boot 3 + MinIO集群 + Nginx 负载均衡 实现图片(头像)的上传 + 更新替换 + 下载 简单案例

通过docker-compose实现了MinIO集群和Nginx的负载均衡,通过Spring Boot 整合MinIo实现图片的上传和下载。

Logic-Driven Thought Engineering 2113
上一篇: FlieBeat & Kafka & Clickhouse 替代ELK 系列一
下一篇: 浅拷贝和深拷贝的区别?
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值