目录:
一、什么是对象存储OSS
二、基本概念
2.1、存储空间(Bucket)
2.2、对象/文件(Object)
2.3、Region(地域)
2.4、Endpoint(访问域名)
2.5、AccessKey(访问密钥)
2.6、强一致性
2.7、数据冗余机制
2.8、OSS 与文件系统的对比
三、应用场景
3.1、图片和音视频等应用的海量存储
3.2、网页或者移动应用的静态和动态资源分离
3.3、云端数据处理
四、实战演练
4.1、创建 Bucket
4.2、文件管理
4.3、SpringBoot整合OSS,实现上传,下载以及查看
4.3.1、前期准备
4.3.2、配置application-oss.properties
4.3.3、创建一个配置类
4.3.4、文件上传到OSS
4.3.5、从OSS下载到本地
4.3.6、查看OSS存在的文件
一、什么是对象存储OSS
阿里云对象存储OSS(Object Storage Service)是阿里云提供的海量、安全、低成本、高可靠的云存储服务。其数据设计持久性不低于99.9999999999%(12个9),服务可用性(或业务连续性)不低于99.995%。
OSS具有与平台无关的RESTful API接口,您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
二、基本概念
2.1、存储空间(Bucket)
存储空间是用户用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间。存储空间具有各种配置属性,包括地域、访问权限、存储类型等。用户可以根据实际需求,创建不同类型的存储空间来存储不同的数据。
- 同一个存储空间的内部是扁平的,没有文件系统的目录等概念,所有的对象都直接隶属于其对应的存储空间。
- 每个用户可以拥有多个存储空间。
- 存储空间的名称在 OSS 范围内必须是全局唯一的,一旦创建之后无法修改名称。
- 存储空间内部的对象数目没有限制。
存储空间的命名规范如下:
- 只能包括小写字母、数字和短横线(-)。
- 必须以小写字母或者数字开头和结尾。
- 长度必须在 3–63 字节之间。
2.2、对象/文件(Object)
对象是 OSS 存储数据的基本单元,也被称为 OSS 的文件。对象由元信息(Object Meta),用户数据(Data)和文件名(Key)组成。对象由存储空间内部唯一的 Key 来标识。对象元信息是一组键值对,表示了对象的一些属性,比如最后修改时间、大小等信息,同时用户也可以在元信息中存储一些自定义的信息。
对象的生命周期是从上传成功到被删除为止。在整个生命周期内,只有通过追加上传的 Object 可以继续通过追加上传写入数据,其他上传方式上传的 Object 内容无法编辑,您可以通过重复上传同名的对象来覆盖之前的对象。
对象的命名规范如下:
- 使用 UTF-8 编码。
- 长度必须在 1–1023 字节之间。
- 不能以正斜线(/)或者反斜线(\)开头。
2.3、Region(地域)
Region 表示 OSS 的数据中心所在物理位置。Region 是在创建 Bucket 的时候指定的,一旦指定之后就不允许更改。该 Bucket 下所有的 Object 都存储在对应的数据中心,目前不支持 Object 级别的 Region 设置。
2.4、Endpoint(访问域名)
Endpoint 表示 OSS 对外服务的访问域名。OSS 以 HTTP RESTful API 的形式对外提供服务,当访问不同的 Region 的时候,需要不同的域名。通过内网和外网访问同一个 Region 所需要的 Endpoint 也是不同的。
2.5、AccessKey(访问密钥)
AccessKey(简称 AK)指的是访问身份验证中用到的 AccessKeyId 和 AccessKeySecret。OSS 通过使用 AccessKeyId 和 AccessKeySecret 对称加密的方法来验证某个请求的发送者身份。AccessKeyId 用于标识用户;AccessKeySecret 是用户用于加密签名字符串和 OSS 用来验证签名字符串的密钥,必须保密。对于 OSS 来说,AccessKey 的来源有:
- Bucket 的拥有者申请的 AccessKey。
- 被 Bucket 的拥有者通过 RAM 授权给第三方请求者的 AccessKey。
- 被 Bucket 的拥有者通过 STS 授权给第三方请求者的 AccessKey。
2.6、强一致性
Object 操作在 OSS 上具有原子性,操作要么成功要么失败,不会存在有中间状态的 Object。OSS 保证用户一旦上传完成之后读到的 Object 是完整的,OSS 不会返回给用户一个部分上传成功的 Object。
Object 操作在 OSS 上同样具有强一致性,用户一旦收到了一个上传(PUT)成功的响应,该上传的 Object 就已经立即可读,并且 Object 的冗余数据已经写成功。不存在一种上传的中间状态,即 read-after-write 却无法读取到数据。对于删除操作也是一样的,用户删除指定的 Object 成功之后,该 Object 立即变为不存在。
2.7、数据冗余机制
OSS 采用数据冗余存储机制,将每个对象的不同冗余存储在同一个区域内多个设施的多个设备上,确保硬件失效时的数据可靠性和可用性。
- OSS Object 操作具有强一致性,用户一旦收到了上传/复制成功的响应,则该上传的 Object 就已经立即可读,且数据已经冗余写入到多个设备中。
- OSS 会通过计算网络流量包的校验和,验证数据包在客户端和服务端之间传输中是否出错,保证数据完整传输。
- OSS 的冗余存储机制,可支持两个存储设施并发损坏时,仍维持数据不丢失。
a.当数据存入 OSS 后,OSS 会检测和修复丢失的冗余,确保数据可靠性和可用性。
b. OSS 会周期性地通过校验等方式验证数据的完整性,及时发现因硬件失效等原因造成的数据损坏。当检测到数据有部分损坏或丢失时,OSS 会利用冗余的数据,进行重建并修复损坏数据。
2.8、OSS 与文件系统的对比
三、应用场景
3.1、图片和音视频等应用的海量存储
OSS可用于图片、音视频、日志等海量文件的存储。各种终端设备、Web网站程序、移动应用可以直接向OSS写入或读取数据。OSS支持流式写入和文件写入两种方式。
3.2、网页或者移动应用的静态和动态资源分离
利用海量互联网带宽,OSS可以实现海量数据的互联网并发下载。OSS提供原生的传输加速功能,支持上传加速、下载加速,提升跨国、跨洋数据上传、下载的体验。
3.3、云端数据处理
上传文件到OSS后,可以配合媒体处理服务和图片处理服务进行云端的数据处理。
四、实战演练
前提:开始使用"对象存储OSS"首先要进入到阿里云控制台,控制台地址:https://oss.console.aliyun.com/overview
4.1、创建 Bucket
进入控制台,选择对象存储。然后点击创建Bucket,如下图所示
4.2、文件管理
进入刚才创建的Bucket中,进行文件在线管理,如图所示
4.3、SpringBoot整合OSS,实现上传,下载以及查看
4.3.1、前期准备
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>
4.3.2、配置application-oss.properties
##########阿里云对象存储OSS###################
aliyun.endpoint=oss-cn-shanghai.aliyuncs.com
aliyun.accessKeyId=*******
aliyun.accessKeySecret=*******
aliyun.bucketName=phone-xby
aliyun.urlPrefix=http://phone-xby.oss-cn-shanghai.aliyuncs.com/
4.3.3、创建一个配置类
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
*
* @author Xiby
*
*/
@Configuration
@PropertySource(value = {"classpath:application-oss.properties"})
@ConfigurationProperties(prefix = "aliyun")
@Data
public class AliyunConfig {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
private String urlPrefix;
@Bean
public OSS oSSClient() {
return new OSSClient(endpoint, accessKeyId, accessKeySecret);
}
}
4.3.4、文件上传到OSS
4.3.4.1、Controller类
@Controller
public class AiliyunOSSController {
@Autowired
private AiliyunOSSService ailiyunOSSlService;
/**
* @param uploadFile
* @return
* @desc 上传文件到OOS
*/
@RequestMapping(value = {"/ailiyunOSS/uplodeFile"}, method = RequestMethod.POST)
@ResponseBody
public Message uplodeFile(@RequestParam("file") MultipartFile uploadFile) {
return ailiyunOSSlService.upload( uploadFile );
}
}
4.3.4.2、Service类
import cn.hutool.core.date.DateTime;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;
@Service
public class AiliyunOSSServiceImpl implements AiliyunOSSService {
private static final Logger logger = LoggerFactory.getLogger( Thread
.currentThread().getStackTrace()[1].getClassName() );
@Autowired
private OSS ossClient;
@Autowired
private AliyunConfig aliyunConfig;
@Override
public Message upload(MultipartFile uploadFile) {
Message m = new Message();
String fileName = uploadFile.getOriginalFilename();
try {
ossClient.putObject( aliyunConfig.getBucketName(), fileName, new
ByteArrayInputStream( uploadFile.getBytes() ) );
} catch (Exception e) {
e.printStackTrace();
//上传失败
m.setResult( "002" );
m.setDetail( "文件上传失败" );
return m;
}
m.setResult( "001" );
m.setDetail( "文件上传成功" );
logger.info( "OSS存储路径:{URL=" + this.aliyunConfig.getUrlPrefix() + fileName + "}" );
return m;
}
}
4.3.4.3.前端(Layui)
<div class="layui-form-item" style="margin: 10px 0;">
<label class="layui-form-label">所属阶段</label>
<div class="layui-input-block">
<button type="button" class="layui-btn" id="test1">
<i class="layui-icon"></i>导入
</button>
</div>
</div>
var uploadInst = upload.render({
elem: '#test1' //绑定元素
,url: '/ailiyunOSS/uplodeFile' //上传接口
,exts:'jpg|png|gif|bmp|jpeg|txt|word|docx|mp4|pdf|doc|xlsx|xls|pptx|ppt|wmv'
,size:0
,done:function () {
initTable();
}
});
4.3.5、从OSS下载到本地
4.3.5.1、Controller类
/**
*
* @author Xiby
*
* @desc 根据文件名下载oss上的文件
*
* @Param fileNames
*/
@RequestMapping(value = {"/ailiyunOSS/exportFile/{fileNames:.*}"}, method = RequestMethod.GET)
@ResponseBody
public void downloadFile(@PathVariable("fileNames") String fileNames,HttpServletResponse response){
HttpHeaders headers = new HttpHeaders();
headers.setContentType( MediaType.APPLICATION_OCTET_STREAM );
ailiyunOSSlService.downloadFile(fileNames,response);
}
4.3.5.2、Servicel类
@Override
public void downloadFile(String fileNames, HttpServletResponse response) {
try {
OSSObject ossObject = ossClient.getObject( aliyunConfig.getBucketName(), fileNames );
BufferedInputStream in = new BufferedInputStream( ossObject.getObjectContent() );
BufferedOutputStream out = new BufferedOutputStream( response.getOutputStream() );
response.setHeader( "Content-Disposition", "attachment;filename=" + URLEncoder.encode( fileNames, "utf-8" ) );
byte[] car = new byte[1024];
int L = 0;
while ((L = in.read( car )) != -1) {
out.write( car, 0, L );
}
if (out != null) {
out.flush();
out.close();
}
if (in != null) {
in.close();
}
ossClient.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
4.3.5.3、前端
<a class="layui-btn layui-btn-xs export" lay-event="exportCsv">下载</a>
var $form = $('<form method="GET"></form>');
$form.attr('action', '/ailiyunOSS/exportFile/'+ encodeURI(fileNames));
$form.appendTo($('body'));
$form.submit();
4.3.6、查看OSS存在的文件
4.3.6.1、Controller类
@RequestMapping("/ailiyunOSS/queryFile")
@ResponseBody
public GriddataPageinfo list()
throws Exception {
return this.ailiyunOSSlService.list();
}
4.3.6.2、Service类
@Override
public GriddataPageinfo list() {
final int maxKeys = 100;
ObjectListing objectListing = ossClient.listObjects( new ListObjectsRequest( aliyunConfig.getBucketName() ).withMaxKeys( maxKeys ) );
List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
return new GriddataPageinfo( sums.size(), sums );
}
4.3.6.3、前端
var initTable = function () {
tObj = table.render({
id:'testReload',
elem: '#datagrid',
height: 500,
url: web_path + '/ailiyunOSS/queryFile',
response: {
countName: 'total',
dataName: 'rows'
},
page: true,
cols: [[
{field: 'bucketName',width: 200, title: '文件管理'},
{field: 'lastModified',width: 200, title: '上传时间'},
{field: 'key',width: 800, title: '文件存储路径'},
{field: 'size',width: 225, title: '文件大小(B)'},
{field: 'tools',fixed: 'right', title: '操作', align: 'center', toolbar: '#showBar',width:150}
]]
});
};
目前文章就介绍到这里了,想要查看了解更多更详细的对象存储OSS的操作,请查看官方文档
本文参考文献:https://help.aliyun.com/document_detail/31817.html?spm=a2c4g.11186623.6.543.1fa66820dbcDTj