如果想搭建一个优雅、简单、功能完备的静态资源服务,那就用MinIO吧。

1 引言

开发 Web 项目过程中,经常需要处理静态资源(如图片、视频、音频,js库 ,css 库等),一般来说,若项目中需要用到这些资源文件,我们常用的有以下几种方法:

  • 本地存储:即在项目工程中的 static 目录下,建立 js/css/icon/font/image/lib/audio/video 等目录,分别存放对应格式的资源文件。使用时,在 html 文件中使用相对位置引用进行。
  • 使用代理搭建静态资源服务:即把资源存放于某一文件目录,使用代理服务器(如 nginx ,apache等)对目录进行映射,构建成资源服务。使用时,在 html 文件中使用代理服务的 url 地址进行引用。
  • 使用第三方工具搭建静态资源服务:使用第三方开源的文件存储或对象存储工具,或者自己写个程序实现可以获取文件的接口。使用时,使用对应的 url 地址或接口地址。
  • 使用在线静态资源服务:如阿里云、CDN等服务。

对于本地存储,缺点就很明显,资源与代码文件混合一起,没有必要,而且不方便扩展。对于本地内部部署的应用,显然是自己搭建静态资源服务比较稳妥。对于使用代理服务和第三方工具,相比起来,代理服务仅做映射,虽然可用,但功能单一,仅做映射,没有其它管理功能,也不方便扩展。使用第三方文件或对象存储工具,可以对文件进行管理、也能考虑高扩展,高性能、高可用等因素,因此是很好的选择,其中,MinIO 就是这样一款好用的对象存储工具,简单,快捷而且功能完备。

本文则是通过对 MinIO 的安装、配置与使用,构建静态资源服务,从而把图片、视频、音频,第三方 js 库等资源独立部署,访问;还会对 MinIO 提供的 Java API 进行使用简单介绍,以便于进一步开发。

2 MinIO 简介

MinIO 官方介绍,MinIO 是高性能的对象存储(块存储、文件存储和对象存储的区别,可参考架构师都知道的分布式对象存储解决方案),兼容 Amazon S3 接口,充分考虑开发人员的需求和体验;支持分布式存储,具备高扩展性、高可用性;部署简单但功能丰富。官方的文档也很详细。它有多种不同的部署模式(单机部署,分布式部署)。为什么说 MinIO 简单易用,原因就在于它的启动、运行和配置都很简单。可以通过 docker 方式进行安装运行,也可以下载二进制文件,然后使用脚本运行。

本文以最简单的方式进行讲解,在 linux 机器中,单机部署,运行二进制文件。

3 MinIO 运行与静态资源使用

3.1 MinIO 获取

MinIO 开发文档中,下载地址如下:

  • linux: https://dl.min.io/server/minio/release/linux-amd64/minio
  • windows: https://dl.min.io/server/minio/release/windows-amd64/minio.exe

本文在 linux 中运行。

3.2 MinIO 启动与运行

3.2.1 前台简单启动

把下载的 minio 文件存放到某个目录作为运行目录(如 /opt/minio),新建一个目录(如/opt/minio-data)作为 minio 数据存储位置,即可启动,如下脚本:

cd /opt/minio
chmod +x minio
./minio server /opt/minio-data

启动后会输出访问地址 endpoint 和对应的 access_key 和 secret_key,使用浏览器访问 endpoint 地址,若可以访问,则表示 minio 已经安装成功。不过这样启动会有几个缺点:

  • 不是后台运行,ctrl+c 就会结束进程,服务就停止
  • 没有自定义访问的用户名密码
  • 没有指定访问IP和端口
  • 日志没有保留到文件

针对这些问题,建议使用下面的方式进行启动运行。

3.2.2 后台指定参数运行

使用 nohup 在后台运行程序,同时指定密码参数,访问地址参数和日志输出,如下所示。

MINIO_ACCESS_KEY=minio MINIO_SECRET_KEY=minio123 nohup /opt/minio/minio  server --address "${MINIO_HOST}:${MINIO_PORT}" /opt/minio-data  > /opt/minio/minio.log 2>&1 &

MINIO_ACCESS_KEYMINIO_SECRET_KEY 是访问密码

${MINIO_HOST}:${MINIO_PORT} 分别是访问的 host 和端口,请按实际情况修改。

这样,通过浏览器访问地址 ${MINIO_HOST}:${MINIO_PORT} ,使用指定的 MINIO_ACCESS_KEYMINIO_SECRET_KEY 登录即可。

3.2.3 创建 bucket 并指定访问策略

在浏览器中登录到 MinIO 存储系统,点击右下角创建 bucket 来存储对象,分别创建对应的 bucket 以存放静态资源:image,video,audio。这样,就可以按资源类型在对应的 bucket 中进行文件上传了,上传后可以把文件分享,其它地方可以通过分享的 url 获取资源,如下图所示。

MinIO 默认的策略是分享地址的有效时间最多是7天,要突破这种限制,可以在 bucket 中进行策略设置。点击对应的 bucket ,edit policy 添加策略 *.*Read Only,如下:

如此就放开了访问,没有时间限制,同时只需要按http://${MINIO_HOST}:${MINIO_PORT}/${bucketName}/${fileName} 则可直接访问资源(不需要进行分享操作)。

关于 MinIO 目录的误区

  • 其实对于对象存储来说,其实不区分文件还是目录,所有文件和目录都是对象,即 image/temp/xxx.jpg 和 image/temp/ 都是对象。它跟操作系统的文件系统的树状结构有本质区别。
  • 上传文件时,objectName 可以是 /temp/xxx.jpg,可以认为系统自动创建了temp目录。
  • MinIO 不会提供像删除目录,同时删除此目录下所有文件的操作(即 rm -rf image/temp),因此要想把目录 image/temp 删除,则需要先把以 image/temp 为前缀的所有文件删除。
  • 查询多个文件时,可以使用前缀匹配方式获取,见 API 文档 listObjects(bucketName, prefix, recursive)

3.3 在 html 文件中引用静态资源

通过上面的设置与运行,MinIO 作为静态资源服务器已经完成,可以写个 html 来引用 MinIO 中的静态资源。如下是测试的 html 里面的图片、视频、音频均使用 MinIO 的资源地址。

<div class="img-list">
<img src="http://${MINIO_HOST}:${MINIO_PORT}/image/test.jpg" alt="图片">
</div>
<div class="audio-list">
<audio src="http://${MINIO_HOST}:${MINIO_PORT}/audio/test.mp3"
controls="controls"></audio>
</div>
<div class="video-list">
<video src="http://${MINIO_HOST}:${MINIO_PORT}/video/test.mp4" controls="controls"></video>
</div>

可发现资源是可以正常加载访问的。

4 Java 客户端 API 操作

MinIO 对开发者是非常友好的,提供了各种语言的 API 操作接口,具体可以参考 MinIO开发文档。下面以 Java 为例做一下测试。

4.1 添加依赖

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

4.2 使用 Java API 进行文件操作

建立 MinIO 的操作客户端 minioClient = new MinioClient(endpoint, accessKey, secretKey);,参数中endpoint 是 MinIO 的访问地址,后面两对应启动时设置的密码。

4.2.1 上传文件

/**
* 上传文件
* @param minioClient 操作客户端
* @param bucketName 上传的bucket名称
* @param objectName 上传后存储在bucket中的文件名
* @param filePath 上传的本地文件路径
*/
public void uploadFile(MinioClient minioClient, String bucketName, String objectName, String filePath) throws XmlPullParserException, NoSuchAlgorithmException, InvalidKeyException, IOException {
try {
// 若不存在bucket,则新建
boolean isExist = minioClient.bucketExists(bucketName);
if (!isExist) {
minioClient.makeBucket(bucketName);
}
// 使用 putObject 上传文件
minioClient.putObject(bucketName, objectName, filePath, null, null, null, null);
} catch (MinioException e) {
System.out.println("Error occurred: " + e);
}
}

4.2.2 下载文件

/**
* 下载文件
*
* @param minioClient 操作客户端
* @param bucketName 上传的bucket名称
* @param objectName 上传后存储在bucket中的文件名
* @param downloadPath 下载文件保存路径
*/
public void downloadFile(MinioClient minioClient, String bucketName, String objectName, String downloadPath) throws XmlPullParserException, NoSuchAlgorithmException, InvalidKeyException, IOException {
File file = new File(downloadPath);
try (OutputStream out = new FileOutputStream(file)) {
InputStream inputStream = minioClient.getObject(bucketName, objectName);
byte[] tempbytes = new byte[1024];
int byteread = 0;
while ((byteread = inputStream.read(tempbytes)) != -1) {
out.write(tempbytes, 0, byteread);
}
} catch (MinioException e) {
System.out.println("Error occurred: " + e);
}
}

4.2.3 删除文件

删除文件简单,使用removeObject即可。

minioClient.removeObject(bucketName, objectName);

4.2.4 列出文件

/**
* 罗列文件
* @param minioClient
* @param bucketName
*/
public void listFile(MinioClient minioClient, String bucketName) throws XmlPullParserException, NoSuchAlgorithmException, InvalidKeyException, IOException {
try {
Iterable<Result<Item>> results = minioClient.listObjects(bucketName);
Iterator<Result<Item>> iterator = results.iterator();
while (iterator.hasNext()) {
Item item = iterator.next().get();
System.out.println(item.objectName() + ", " + item.objectSize() + "B");
}
} catch (MinioException e) {
System.out.println("Error occurred: " + e);
}
}

5 总结

由于有对静态资源进行独立访问的需求,进行动静分离,通过使用 MinIO ,可以快速简单的实现静态资源服务器,以供访问。本文通过对 MinIO 的下载、部署、启动、运行、配置等描述,并以 html 引用静态资源文件为例,讲解 MinIO 的使用,并提供 Java API 的简单使用。希望对大家有帮助。

资源下载

本文中使用了 nohup 对 MinIO 进行启动,但命令太长,一般我们都会写成脚本,以实现启动、关闭及状态查询,因此,我把脚本写成完整的 sh 文件,以供大家使用。另外,MinIO Java API 的测试,本示例使用的是 Spring Boot 项目,以单元测试的方式进行。

sh脚本文件及 Spring Boot 工程一起放在我的 minio github 示例 中(脚本minio-serviced.sh 在 scripts 目录下),有需要的可下载参考。

脚本使用方法:

  • 根据实际情况修改sh脚本中的参数
  • 修改执行权限:chmod +x minio-serviced.sh
  • 按参数启动/关闭/重启/运行状态:./minio-serviced.sh start/stop/restart/status

参考资料

往期文章

我的公众号(搜索Mason技术记录),获取更多技术记录:

利用 MinIO 轻松搭建静态资源服务的更多相关文章

  1. 使用Node.js搭建静态资源服务器

    对于Node.js新手,搭建一个静态资源服务器是个不错的锻炼,从最简单的返回文件或错误开始,渐进增强,还可以逐步加深对http的理解.那就开始吧,让我们的双手沾满网络请求! Note: 当然在项目中如 ...

  2. 二.Nginx反向代理和静态资源服务配置

    2018年03月31日 10:30:12 麦洛_ 阅读数:1362更多 所属专栏: nginx   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/M ...

  3. 使用 Nginx 搭建静态资源 web 服务器

    在搭建网站的时候,往往会加载很多的图片,如果都从 Tomcat 服务器来获取静态资源,这样会增加服务器的负载,使得服务器运行 速度非常慢,这时可以使用 Nginx 服务器来加载这些静态资源,这样就可以 ...

  4. web站点优化之使用tengine搭建静态资源服务器,静态资源合并加载案例剖析

    在一个项目还是单体架构的时候,所有的js,css,image都会在一个web网站上,看起来并没有什么问题,比如下面这样: 但是当web网站流量起来的时候,这个单体架构必须要进行横向扩展,而在原来的架构 ...

  5. 命令级的python静态资源服务。

    python -m SimpleHTTPServer 在当前目录起python静态资源服务.

  6. 《前端运维》二、Nginx--3静态资源服务、跨域与其他

    一.静态资源服务 首先,静态资源一般是指客户端发送请求到Web服务器,web服务器从内存中取得相应的文件,返回给客户端,客户端解析并渲染出来.动态资源呢,则是由客户端发起请求,先交由web容器,web ...

  7. Nginx配置实例-动静分离实例:搭建静态资源服务器

    场景 Nginx入门简介和反向代理.负载均衡.动静分离理解: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/102790862 U ...

  8. SpringBoot - 搭建静态资源存储服务器

    目录 前言 环境 实现效果 具体实现 文件上传 配置类 上传接口 上传实现 辅助类 实体 上传测试 文件访问 配置类 项目源码 前言 记录下SpringBoot下静态资源存储服务器的搭建. 环境 wi ...

  9. Nginx学习之从零搭建静态资源网站

    前言   在某学习网站学习了nginx的安装和使用,以此文记录. 环境准备   安装在VMWare下的Centos虚拟机.由于我这是新装的虚拟机.所以很多插件都没有,这里干脆一次性安装上. wget ...

随机推荐

  1. Y事业部打造一体化质量管理平台

    互联网企业质量管理的困惑 作为互联网时代的互联网企业,我们的研发模式和传统模式相比,最显著的不同在于发布节奏加快了,这个加快不是快了10%,20%,50%,而是加快了几倍,甚至几十倍,上百倍.面对加快 ...

  2. Github 绑定域名添加https的方法 2019年9月更新

    官方教程 https://help.github.com/en/articles/using-a-custom-domain-with-github-pages 打开 https://github.c ...

  3. Simpo

    Time: 2017-01-16 - Download Github: https://github.com/KeliCheng/Simpo一款快速发布文字和图片到社交网站的macOS菜单栏App,目 ...

  4. Spring Boot 2.x基础教程:使用 Thymeleaf开发Web页面

    通过本系列教程的前几章内容(API开发.数据访问).我们已经具备完成一个涵盖数据存储.提供HTTP接口的完整后端服务了.依托这些技能,我们已经可以配合前端开发人员,一起来完成一些前后端分离的Web项目 ...

  5. alibaba开发手册

    alibaba开发手册 11.19 强制: 方法参数在定义和传入时,多个参数逗号后边必须加空格. ​ IDE 的 text file encoding 设置为 UTF-8; IDE 中文件的换行符使用 ...

  6. 完整版EXCEL导出 (大框架SpringCloud 业务还是Springboot一套)

    这里用的是easypoi 首先引入jar包 <!-- excel --><dependency> <groupId>cn.afterturn</groupId ...

  7. Hibernate入门之注解@Column详解

    前言 上一节我们讲解了Hibernate的主键生成策略,本节我们继续来讲讲Hibernate中针对列的映射即@Column注解,文中若有错误之处,还望指正. @Column注解详解 我们看到如上针对列 ...

  8. ubuntu下安装typescript

    安装ts之前需要安装好node, 安装ts: 1. npm install -g typescript /opt/node/bin/tsc -> /opt/node/lib/node_modul ...

  9. 阿里云上docker部署nginx实现反向代理

    简介   需要从镜像仓库找到所需要的nginx版本pull下来.(地址:https://hub.docker.com/) 1.docker pull nginx 1.挂载目录 1.1 获取nginx. ...

  10. 负载均衡框架 ribbon 一

    Ribbon开源地址:https://github.com/Netflix/ribbon/wiki/Getting-Started 1.Ribbon简介 负载均衡框架,支持可插拔式的负载均衡规则 支持 ...