什么是 MinIO?
官方定义:MinIO是一个软件定义的高性能分布式对象存储服务器。 您可以在消费级或企业级硬件上运行MinIO, 支持多种操作系统和架构。
通俗一点,就是以对象的形式作为存储结构来存储为文件。
为什么选择minio来作为对象存储服务?
废话少说,直接问AI。
-
开源和可扩展性:
开源:MinIO是开源的,这意味着你可以自由地使用、修改和分发它,这对于希望避免供应商锁定的企业和开发者来说是一个巨大的优势。可扩展性:MinIO设计用于横向扩展,可以轻松地通过添加更多节点来增加存储容量和处理能力。 -
高性能:
MinIO针对性能进行了优化,提供高速的对象存储服务,适合用于大数据、机器学习和高性能计算等场景。 -
兼容性:
MinIO与Amazon S3 API兼容,这意味着你可以使用现有的S3工具和应用程序与MinIO无缝协作。 -
简单易用:
MinIO的安装和配置相对简单,提供了直观的命令行界面和图形用户界面。 -
安全性:
MinIO支持多种安全特性,包括自动加密、访问控制列表(ACLs)和身份验证。 -
成本效益:
由于MinIO是开源的,它可以帮助企业节省昂贵的许可费用,同时提供与商业对象存储服务相似的功能。
性能好,简单易用,安全性高。
安装和部署
就从学习来讲的话(学习他的使用,我用java和他交互),由于有docker,所以我采用docker部署的方式。
docker run -p 9000:9000 -p 9090:9090 --net=host --name myminio -d --restart=always -e "MINIO_ACCESS_KEY=admin" -e "MINIO_SECRET_KEY=Qhx20040819" -v /home/minio/data:/data -v /home/minio/config:/root/.minio minio/minio server /data --console-address ":9090" -address ":9000"
这里解释一下。
MINIO_ACCESS_KEY :账号
MINIO_SECRET_KEY :密码(账号长度必须大于等于5,密码长度必须大于等于8位)
windows安装minio:Windows安装Minio(超详细)_minio windows安装-CSDN博客
Linux安装minio:Linux安装MinIO(图文解说详细版)-CSDN博客
启动完之后。
访问:ip:port
跳转到该页面。
输入上文指定的ACCESS_KEY、SECRET_KEY分别作为账号、密码填进去。
进入到该页面差不多就可以了。
使用
其实具体来讲使用的时候还要创建一个Bucket。
在对象存储服务(Object Storage Service)中,Bucket(桶)是用于组织和管理存储在云中的对象(文件)的基本容器。Bucket类似于文件系统中的目录或文件夹,用于存储、检索和保护数据。
说白了就是个文件夹。存储的时候,需要具体知道存储在那个文件夹里面。
基于java的整合。
这里就直接参考ry-vue-plus的源码了。以及提前了解一个概念。
什么是AWS s3规范?
AWS S3(Simple Storage Service)是亚马逊提供的一项云存储服务,它定义了一套 API 接口,用于与对象存储服务进行交互。这些接口允许开发者使用 RESTful API、SOAP API 或 AWS SDK 访问对象存储服务,执行诸如创建、读取、更新和删除对象等操作。
minio实现了这套规范。
了解这个概念之后,我在再来看,ry-common-oss的源码。
他做了一张表,用来专门管理对象存储服务的access_key、secre_key、bucket、endpoint这种核心字段。然后,一开始程序初始化oss配置。将表中默认选中的oss配置加载到缓存中。
当我们第一次使用文件上传功能时。
在OssFactorya中instance方法中,从缓存拿取默认的oss配置信息,然后转换为OssClient对象,缓存到CLIENT_CACHE,这是一个线程安全的map。
@Slf4j
public class OssFactory {
private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>();
private static final ReentrantLock LOCK = new ReentrantLock();
/**
* 获取默认实例
*/
public static OssClient instance() {
// 获取redis 默认类型
String configKey = RedisUtils.getCacheObject(OssConstant.DEFAULT_CONFIG_KEY);
if (StringUtils.isEmpty(configKey)) {
throw new OssException("文件存储服务类型无法找到!");
}
return instance(configKey);
}
/**
* 根据类型获取实例
*/
public static OssClient instance(String configKey) {
String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey);
if (json == null) {
throw new OssException("系统异常, '" + configKey + "'配置信息不存在!");
}
OssProperties properties = JsonUtils.parseObject(json, OssProperties.class);
// 使用租户标识避免多个租户相同key实例覆盖
String key = configKey;
if (StringUtils.isNotBlank(properties.getTenantId())) {
key = properties.getTenantId() + ":" + configKey;
}
OssClient client = CLIENT_CACHE.get(key);
// 客户端不存在或配置不相同则重新构建
if (client == null || !client.checkPropertiesSame(properties)) {
LOCK.lock();
try {
client = CLIENT_CACHE.get(key);
if (client == null || !client.checkPropertiesSame(properties)) {
CLIENT_CACHE.put(key, new OssClient(configKey, properties));
log.info("创建OSS实例 key => {}", configKey);
return CLIENT_CACHE.get(key);
}
} finally {
LOCK.unlock();
}
}
return client;
}
}
然后再回到OssClient对象中,用读取的Oss配置信息,创建了S3AsyncClient、S3TransferManager这两个类型的对象。
......
/**
* 构造方法
*
* @param configKey 配置键
* @param ossProperties Oss配置属性
*/
public OssClient(String configKey, OssProperties ossProperties) {
this.configKey = configKey;
this.properties = ossProperties;
try {
// 创建 AWS 认证信息
StaticCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
AwsBasicCredentials.create(properties.getAccessKey(), properties.getSecretKey()));
//MinIO 使用 HTTPS 限制使用域名访问,站点填域名。需要启用路径样式访问
boolean isStyle = !StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE);
//创建AWS基于 CRT 的 S3 客户端
this.client = S3AsyncClient.crtBuilder()
.credentialsProvider(credentialsProvider)
.endpointOverride(URI.create(getEndpoint()))
.region(of())
.targetThroughputInGbps(20.0)
.minimumPartSizeInBytes(10 * 1025 * 1024L)
.checksumValidationEnabled(false)
.forcePathStyle(isStyle)
.build();
//AWS基于 CRT 的 S3 AsyncClient 实例用作 S3 传输管理器的底层客户端
this.transferManager = S3TransferManager.builder().s3Client(this.client).build();
// 创建 S3 配置对象
S3Configuration config = S3Configuration.builder().chunkedEncodingEnabled(false)
.pathStyleAccessEnabled(isStyle).build();
// 创建 预签名 URL 的生成器 实例,用于生成 S3 预签名 URL
this.presigner = S3Presigner.builder()
.region(of())
.credentialsProvider(credentialsProvider)
.endpointOverride(URI.create(getDomain()))
.serviceConfiguration(config)
.build();
// 创建存储桶
createBucket();
} catch (Exception e) {
if (e instanceof OssException) {
throw e;
}
throw new OssException("配置错误! 请检查系统配置:[" + e.getMessage() + "]");
}
}
......
说白了,嗯,更多是思想的体现,既然minio、aliyun、qiniu、qcloud,都遵循了这套规范,他把公共封装出来,当我们后面换用oss存储服务的时候,只要它遵循oss规范,我们就可以通过先表中添加新的配置信息即可。