解决方案

文件存储解决方案-云存储阿里 OSS

seo靠我 2023-09-23 21:10:04

文件存储解决方案-云存储阿里 OSS

1.文件存储(上传)解决方案讨论

1.图解

文件存储解决方案-云存储阿里 OSS

解读上图

普通上传并不是分布式,也不是集群,可用性不高普通上传的分布式情况,使用了集群,但SEO靠我是当把文件存储在集群中的某台服务器,当下次读取时,因为负载均衡,存在读取不到的文件问题应用服务器使用集群,文件存储通过网关提供统一接口来存储文件,可用性高

3.1 方案 1: 自建服务器,成本高, 也存SEO靠我在技术瓶颈

3.2 方案 2: 使用云存储产品(阿里云等), 是企业优选方案

2.对应 分布式 微服务 架构分析

2.阿里云对象存储介绍

1.官网

https://www.aliyun.com/product/SEO靠我oss

2.说明

阿里云对象存储 OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,提供数据高可用性, 多种存储类型供选择,全面优化存储成本

3.上传方式

1SEO靠我.普通上传方式

1.阿里云对象存储-普通上传示意图

2.分析

上传慢:用户数据需先上传到应用服务器,之后再上传到OSS。网络传输时间比直传到OSS多一倍。如果用户数据不通过应用服务器中转,而是直传到OSS,SEO靠我速度将大大提升。

扩展性差:如果后续用户多了,应用服务器会成为瓶颈。

费用高:需要准备多台应用服务器。由于OSS上传流量是免费的,如果数据直传到OSS,

不通过应用服务器,那么将能省下几台应用服务器2.服务SEO靠我端签名后直传

1.阿里云对象存储-服务端签名后直传示意图

2.分析

Web端向服务端请求签名,然后直接上传,不会对服务端产生压力,而且安全可靠。但服务端无法实时了解用户上传了多少文件,上传了什么文件。如果想SEO靠我实时了解用户

上传了什么文件,可以采用服务端签名直传并设置上传回调

3.准备工作

1.注册一个阿里云账号,并完成认证

2.阿里云地址:https://www.aliyun.com/

3.创建阿里云对象 BuckSEO靠我et 创建并测试

4.创建 RAM 用户(访问控制 RAM(Resource Access Management)是阿里云提供的一项管理用户身份与资源访问权限的服务), 得到 accessKeyId 和SEO靠我 accessKeySecret (可以理解成是阿里云子用户的 id 和密码)

具体步骤可以参考:https://llinp.cn/articles/2022/01/02/1641105914205.hSEO靠我tml

5.将得到 endpoint , accessKeyId , accessKeySecret 填写到代码中, 并指定要上传的文

件路径, 阿里云哪个 Bucket 和上传后的文件名是什么

4.使用原SEO靠我生 SDK,上传文件到阿里云对象 Bucket

参考阿里云官方文档 https://help.aliyun.com/document_detail/84781.html#p-yqj-z1w-rl2

,这里SEO靠我我使用的是简单上传-上传文件流的方式。

1.创建一个boot项目引入依赖

<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sSEO靠我dk-oss</artifactId><version>3.5.0</version> </dependency>

2.编写如下一个测试类,进行测试。

@RestController SEO靠我 public class TestController {@RequestMapping("/test")public R test() {// Endpoint以华东1(杭州)为例,其它SEO靠我Region请按实际情况填写。String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";// 阿里云账号AccessKey拥有所有API的访问权SEO靠我限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。String accessKeyId = "你的accessKeyId";String acceSEO靠我ssKeySecret = "你的accessKeySecret";// 填写Bucket名称,例如examplebucket。String bucketName = "你的bucketName";/SEO靠我/ 上传文件名 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。String objectName = "12.jpg";/SEO靠我/ 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。// 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。String filePathSEO靠我 = "C:\\Users\\llp\\Desktop\\solo-fetchupload-7208404724819002506-m0Dvrtu.jpg";// 创建OSSClient实例。OSS SEO靠我ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);try {//文件输入流InputStSEO靠我ream inputStream = new FileInputStream(filePath);// 创建PutObject请求。 将文件流写入到objectName文件中ossClient.putSEO靠我Object(bucketName, objectName, inputStream);} catch (OSSException oe) {System.out.println("Caught anSEO靠我 OSSException, which means your request made it to OSS, "+ "but was rejected with an error response SEO靠我for some reason.");System.out.println("Error Message:" + oe.getErrorMessage());System.out.println("ESEO靠我rror Code:" + oe.getErrorCode());System.out.println("Request ID:" + oe.getRequestId());System.out.prSEO靠我intln("Host ID:" + oe.getHostId());} catch (ClientException ce) {System.out.println("Caught an ClienSEO靠我tException, which means the client encountered "+ "a serious internal problem while trying to communSEO靠我icate with OSS, "+ "such as not being able to access the network.");System.out.println("Error MessagSEO靠我e:" + ce.getMessage());} catch (FileNotFoundException e) {e.printStackTrace();} finally {if (ossClieSEO靠我nt != null) {ossClient.shutdown();}}return R.ok();}}

可以看到文件已经上传到阿里云oss服务器上了

5.使用 SpringCloud Alibaba OSEO靠我SS 传文件到阿里云对象 Bucket

1.引入依赖

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-stSEO靠我arter-alicloud-oss</artifactId><version>2.1.0.RELEASE</version> </dependency>

2.编写yaml

spring:SEO靠我datasource:username: rootpassword: rooturl: jdbc:mysql://192.168.56.100:3306/llpliving_commodity?useSEO靠我Unicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.jdbc.DSEO靠我rivercloud:alicloud:oss:endpoint: 参考创建bucket时选择的归属区域access-key: 你的keyIdsecret-key: 你的keySecretbucketSEO靠我-name: 你的bucketName

3.编写测试类

@Resourceprivate OSSClient ossClient;@Value("${spring.cloud.alicloud.buckeSEO靠我t-name}")private String bucketName;//上传指定的文件到bucket@RequestMapping("/test2")public R test2() throws SEO靠我FileNotFoundException {String filePath = "C:\\Users\\asus\\Desktop\\solo-fetchupload-720840472481900SEO靠我2506-m0Dvrtu.jpg";String objectName = "13.jpg";InputStream inputStream = new FileInputStream(filePatSEO靠我h);ossClient.putObject(bucketName, objectName, inputStream);ossClient.shutdown();return R.ok();}

6.完成SEO靠我服务端签名后直传

1.文档

https://help.aliyun.com/document_detail/31926.html

2.代码示例

https://help.aliyun.com/documentSEO靠我_detail/91868.htm

3.代码+配置实现

1.引入依赖

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cSEO靠我loud-starter-alicloud-oss</artifactId><version>2.1.0.RELEASE</version> </dependency>

2.编写yamlSEO靠我

server:port: 7070spring:cloud:alicloud:oss:endpoint: oss-cn-chengdu.hangzhou.comaccess-key: 你的accessSEO靠我Keysecret-key: 你的secretKeybucket-name: 你的bucketName

3.配置类,从yaml配置文件中读取配置信息

@Data @Component SEO靠我 @ConfigurationProperties("spring.cloud.alicloud") public class OssProperties implementSEO靠我s InitializingBean {@Value("${spring.cloud.alicloud.oss.endpoint}")private String endpoint;private SSEO靠我tring accessKey;private String secretKey;private String bucketName;public static String ENDPOINT;pubSEO靠我lic static String KEY_ID;public static String KEY_SECRET;public static String BUCKET_NAME;@OverridepSEO靠我ublic void afterPropertiesSet() throws Exception {this.ENDPOINT = endpoint;this.KEY_ID = accessKey;tSEO靠我his.KEY_SECRET = secretKey;this.BUCKET_NAME = bucketName;this.ENDPOINT = endpoint;}}

4.编写测试类

@RestContSEO靠我roller public class OssServiceController {//提示:这里的注入方式是 OSS 接口注入, 不要写成实现类了@Resourceprivate OSEO靠我SS ossClient;/*** 获取文件上传签名/授权* 这段代码从阿里云示例文档拷贝, 并做修改,去掉暂时不用的代码** @return*/@RequestMapping("/oss/policSEO靠我y")public R policy() {// 填写Host地址,格式为https://bucketname.endpoint。String host = "https://" + OssPropeSEO靠我rties.BUCKET_NAME + "." + OssProperties.ENDPOINT;// 设置上传到OSS文件的前缀,可置空此项。置空后,文件将上传至Bucket的根目录下。// 我们可SEO靠我以将文件按照 年-月-日的形式分目录存放在阿里云String format = new SimpleDateFormat("yyyy/MM/dd").format(new Date());// 用户上SEO靠我传文件时指定的前缀。String dir = format + "/";// 创建ossClient实例。OSS ossClient = new OSSClientBuilder().build(OsSEO靠我sProperties.ENDPOINT, OssProperties.KEY_ID, OssProperties.KEY_SECRET);Map<String, String> respMap = SEO靠我null;try {long expireTime = 30;long expireEndTime = System.currentTimeMillis() + expireTime * 1000;DSEO靠我ate expiration = new Date(expireEndTime);PolicyConditions policyConds = new PolicyConditions();policSEO靠我yConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);policyConds.addCoSEO靠我nditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);String postPolicy = ossClient.generSEO靠我atePostPolicy(expiration, policyConds);byte[] binaryData = postPolicy.getBytes("utf-8");String encodSEO靠我edPolicy = BinaryUtil.toBase64String(binaryData);String postSignature = ossClient.calculatePostSignaSEO靠我ture(postPolicy);respMap = new LinkedHashMap<String, String>();respMap.put("accessId", OssPropertiesSEO靠我.KEY_ID);respMap.put("policy", encodedPolicy);respMap.put("signature", postSignature);respMap.put("dSEO靠我ir", dir);respMap.put("host", host);respMap.put("expire", String.valueOf(expireEndTime / 1000));// rSEO靠我espMap.put("expire", formatISO8601Date(expiration));} catch (Exception e) {// Assert.fail(e.getMessaSEO靠我ge());System.out.println(e.getMessage());}return R.ok().put("data", respMap);} }

5.测试

浏览器: httSEO靠我p://localhost:7070/oss/policy

6.前端拿到policy凭证之后,通过policy直接上传到阿里云

import http from @/utils/httpRequest.jSEO靠我s export function policy() {return new Promise((resolve,reject)=>{http({//url: http.adornUrlSEO靠我("/oss/policy"),url: "http://localhost:7070/oss/policy",method: "get",params: http.adornParams({})})SEO靠我.then(({ data }) => {resolve(data);})}); }

7.前端拿到policy直接进行上传会存在跨域问题

8.解决阿里云跨域问题, 设置跨域

数据安全-跨域设SEO靠我

9.再次上传,依然存在问题

10.再次上传,上传成功

“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2