概述
分布式文件系统 (Distributed File System, DFS) 是一种将文件存储在多个计算机上的文件系统,它可以提供高可用性、可扩展性和容错性
分布式文件系统 (Distributed File System, DFS) 是是指文件系统管理的物理存储资源不一定直接连接在本地节点上,而是通过计算机网络与节点(可简单的理解为一台计算机)相连;或是若干不同的逻辑磁盘分区或卷标组合在一起而形成的完整的有层次的文件系统。DFS为分布在网络上任意位置的资源提供一个逻辑上的树形文件系统结构,从而使用户访问分布在网络上的共享文件更加简便。分布式文件系统通常使用分布式存储技术,如分布式哈希表(DHT)、一致性哈希(Consistent Hashing)等,来实现文件的存储和检索。分布式文件系统还可以提供文件共享、数据备份和恢复等功能,以提高数据的可靠性和可用性。
常见存储方案
用途:C端业务用户头像上传,海量图片音频、视频存储,用户行为日志存储
方案一:使用nginx搭建本地图片服务器
方案二:使用开源的分布式文件存储系统,例如MinIO、Fastdfs、HDFS等
例如:MinIO 是在 GNU Affero 通用公共许可证 v3.0 下发布的高性能多云对象存储。
它是与 Amazon S3 云存储服务兼容的 API。非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。使用 MinIO 为机器学习、分析和应用程序数据工作负载构建高性能基础架构。
方案三:使用云存储,例如阿里云OSS、七牛云QiNiu等
例如:OSS存储的特点:
- 不限带宽: 阿里云OSS等云对象存储服务具有全球分布能够提供无限制的带宽而能够快速传输大量的视频数据,确保流畅的视频播放。
- 强大的 API生态: 云对象存储服务通常提供丰富的 API生态系统,这使得开发人员能够轻松构建和扩展应用程序,实现更多功能。
- 更加安全性: 云对象存储服务通常具有高级的安全性特性,如身份认证、访问控制. 数据加密等,确保存储的视频资源安全可靠。
阿里云OSS存储
阿里云官方:https://help.aliyun.com/zh/oss/product-overview/what-is-oss
1.对象存储OSS(Object StorageService)是阿里云提供的海量、安全、低成本、高持久的云存储服务。其数据设计持久性不低于99.9999999999%(12个9),服务设计可用性不低于99.995%。
2.OSS具有与平台无关的RESTful API接口,您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
3.提供标准、低频访问、归档和冷归档四种存储类型,全面覆盖从热到冷的各种数据存储场景。
- 开通阿里云OSS,配置用户
------>登录阿里云------>搜索对象存储OSS------>选择容量进行购买------>开通OSS------>
------>Bucket列表------>创建Bucket------>表单填写(名称,地域,存储类型)------>保存确定------>
------>账户: AccessKey管理------>开始使用子用户AccessKey------>创建用户------>登录名称,访问方式(Open API访问)------>保存确定------>
------>用户信息------>复制AccessKey ID------>复制AccessKey Secret------>后续配置SpringBoot的yml需要设置------> - SpringBoot项目整合OSS
第一步:添加oss-maven依赖
<!-- 阿里云OSS依赖-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
第二步:yml配置OSS账户信息
# 阿里云OSS配置
aliyun:
oss:
end-point: oss-cn-shanghai.aliyuncs.com
access-key-id: LTAI5tJf******************
access-key-secret: Ro44nNU****************
bucket-name: oss-yuan
第三步:读取yml配置,创建OSSConfig
/**
* @description 阿里云OSS配置类
* @author ygt
*/
@ConfigurationProperties(prefix = "aliyun.oss")
@Configuration
@Data
public class OSSConfig {
private String endPoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
}
第四步:编写FileService
public interface FileService {
String uploadVideo(MultipartFile file);
}
第五步:编写实现类FileServiceImpl
package com.function.service.impl;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectResult;
import com.function.config.OSSConfig;
import com.function.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
@Service
@Slf4j
public class FileServiceImpl implements FileService {
@Autowired
private OSSConfig ossConfig;
@Override
public String uploadVideo(MultipartFile file) {
//获取相关配置
String bucketName = ossConfig.getBucketName();
String endPoint = ossConfig.getEndPoint();
String accessKeyId = ossConfig.getAccessKeyId();
String accessKeySecret = ossConfig.getAccessKeySecret();
//创建OSS对象
OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
//获取原生文件名
String originalFilename = file.getOriginalFilename();
//JDK8的日期格式
LocalDateTime time = LocalDateTime.now();
DateTimeFormatter dft = DateTimeFormatter.ofPattern("yyyy/MM/dd");
//拼装OSS上存储的路径
String folder = dft.format(time);
String fileName = generateUUID();
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
//在OSS上bucket下的文件名
String uploadFileName = "user/" + folder + "/" + fileName + extension;
try {
PutObjectResult result = ossClient.putObject(bucketName, uploadFileName, file.getInputStream());
//拼装返回路径
if (result != null) {
return "https://"+bucketName+"."+endPoint+"/"+uploadFileName;
}
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (IOException e) {
log.error("文件上传失败:{}",e.getMessage());
} finally {
//OSS关闭服务,不然会造成OOM
ossClient.shutdown();
}
return null;
}
/**
* 获取随机字符串
* @return
*/
private String generateUUID() {
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
}
}
第六步:编写Controller控制层
@RestController
@RequestMapping("user/file")
@Api(tags = "用户模块--OSS对象存储")
public class OSSFileController {
@Autowired
private FileService fileService;
/**
* 上传
*/
@RequestMapping(value = "/upload", method = {
RequestMethod.GET,RequestMethod.POST})
@ApiOperation(value = "上传")
public ResponseMessage<String> getInfo(HttpServletRequest request,@RequestPart("file") MultipartFile file) throws IOException {
Long userId = JwtUtils.getUserId(request.getHeader(YuanConstants.TOKEN_HEADER_NAME));
return ResponseMessageBuilder.build(ErrorCode.SUCCESS.getCode(),fileService.uploadVideo(file));
}
}
第七步:测试文件上传
第八步:权限配置
授予子用户账户的权限AliyunOSSFullAccess,并在阿里云后台的“权限管理”-“读写权限”中,把 Bucket ACL 修改为 “公共读”,然后保存即可。
第九步:绑定自定义域名至Bucket默认域名
文件上传到OSS后,OSS会使用Bucket默认域名生成文件访问地址。使用浏览器访问该地址时,会触发强制下载行为。如果您的业务不希望暴露Bucket默认域名或有在浏览器中预览文件的需求,您需要为Bucket绑定自定义域名,然后通过自定义域名访问该Bucket中的文件。绑定自定义域名后,不影响继续使用OSS提供的域名。
使用场景:
- 文件预览:通过自定义域名访问OSS Bucket,避免OSS强制增加下载响应头,实现在浏览器中预览文件。
- 品牌形象和专业性:将自定义域名绑定到OSS Bucket,提供个性化域名,增强品牌形象和专业性,增加用户信任度
- 防止域名被拦截:一些应用或平台可能会对Bucket默认域名进行拦截。您可以为Bucket绑定自定义域名,以确保您的OSS Bucket中的资源能够被正常访问。
- 访问方便性:使用自定义域名访问OSS Bucket,方便易记,相比使用OSS默认域名,更简洁友好,轻松访问和分享资源。
- 用户体验优化:通过自定义域名,提高访问速度,结合CDN加速技术,实现快速内容分发和下载,减少延迟,提升用户体验。
- 链接的持久性:绑定自定义域名到OSS Bucket后,即使后续存储位置或服务有变化,用户仍可使用相同域名访问资源,确保链接的持久性,长期可访问和使用存储资源。
技术拓展
提示:@ConditionalOnProperty(name = "ygt-dfs-bucket.type", havingValue = "oss")
ygt-dfs-bucket:
type: oss
oss:
end-point: oss-cn-shanghai.aliyuncs.com
access-key-id: LTAI5tJf******************
access-key-secret: Ro44nNU****************
bucket-name: oss-yuan #如果访问不通,使用动态切换备用地址
qiniu:
end-point: oss-cn-shanghai.aliyuncs.com
access-key-id: LTAI5tJf******************
access-key-secret: Ro44nNU****************
bucket-name: oss-yuan
小结
提示:以上内容只采用了简单上传,标准存储方式
上传方式除了简单上传,还有分片上传、断点续传上传、回调上传、表单上传、追加上传等不同方案,有着丰富的研究性。