性能文章>记一次阿里云oss文件上传服务假死>

记一次阿里云oss文件上传服务假死转载

3周前
179701

引言

记得以前刚开始学习web项目的时候,经常涉及到需要上传图片啥的,那时候都是把图片上传到当前项目文件夹下面,每次项目一重启图片就丢了。虽然可以通过修改/tomcat/conf/server.xml配置文件,配置一个上传图片的本地文件夹,即配置一个工程配置虚拟路径,这样可以避免项目重启图片丢失。自从参加工作以来基本就没有遇到使用这种方式来存储图片了。一般要么自己搭建文件服务器,要么使用付费的文件服务。比如七牛云、阿里云、腾讯云等。今天我们就一起来聊聊如何使用阿里云OSS文件上传。

oss 文件上传

使用OSS文件上传,阿里云提供了如下几种方式,大家可以选择适合自己的方式。

Web端上传

Web端常见的上传方法是用户在浏览器或App端上传文件到应用服务器,应用服务器再把文件上传到OSS。具体流程如下图所示。
在这里插入图片描述
这种方式肯定不可取它有如下去缺点:

  • 上传慢:用户数据需先上传到应用服务器,之后再上传到OSS,网络传输时间比直传到OSS多一倍。如果用户数据不通过应用服务器中转,而是直传到OSS,速度将大大提升。而且OSS采用BGP带宽,能保证各地各运营商之间的传输速度。
  • 扩展性差:如果后续用户数量逐渐增加,则应用服务器会成为瓶颈。本来就已经采用了OSS上传了,然后还要在占用自己服务器。
  • 费用高:需要准备多台应用服务器。由于OSS上行流量是免费的,如果数据直传到OSS,将节省多台应用服务器的费用。
JavaScript客户端签名直传

这种方式采用纯前端直接上传,不经过应用服务器,不过这种方式阿里云给到的一些关于OSS上传的一些核心参数(AccesssKey ID和AccessKey Secret相当于我们在阿里云那边申请的账号和密码)也需要写在前端代码里面,这样就容易导致我们核心参数被泄漏。存在安全隐患。这种方式也不推荐。

服务端签名后直传

前面直接在前端签名上传会有安全隐患,存在参数泄漏。我们可以把参数放在服务端,然服务端和阿里云去交互,这样就不存在核心参数的泄漏。
在这里插入图片描述

如何接入

引入依赖
  • 因为本人是从事java开发的,所以直接引入官方提供最新的maven依赖。
<!-- https://mvnrepository.com/artifact/com.aliyun.oss/aliyun-sdk-oss -->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.14.0</version>
</dependency>

为什么要引入最新的依赖。因为如果遇到什么问题需要找阿里云的人帮忙解决的时候,别人大多数都会问你什么版本的sdk,然后如果遇到那种一时半会比较难解决的问题,人家会推荐你升级最新版本试试。因为可能在最新版本修复了你所遇到的bug。有人可能会说,引入最新版本不就是帮别人踩坑吗?万一解决一个bug又引入两个bug列?这种情况也不是没有可能的。

服务端构建签名

在这里插入图片描述
上图是官网提供的入门例子,代码是一大坨,我们可以看看稍微优化后的代码:
创建一个单例的ossClient,可以复用线程,不需要每次都去new ossClient().

        String host = String.format("https://%s.%s", ossPropertoooies.getBucketName(), ossPropertoooies.getEndpoint());
        long expiredTime = System.currentTimeMillis() + fileOssProperties.getUploadSignatureTtl();
        Date expiration = new Date(expiredTime);

        // 根据文件名和文件类型设置存储路径,可以按照文件类型+日期格式+UUID文件名 进行分割
        String filepath = getFilePath(request.getCategory(), request.getFilename());

        PolicyConditions policyConditions = new PolicyConditions();
        policyConditions.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, fileOssProperties.getUploadSizeLimit());
        policyConditions.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, filepath);

        String postPolicy = ossClient.generatePostPolicy(expiration, policyConditions);
        byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
        String encodedPolicy = BinaryUtil.toBase64String(binaryData);
        String postSignature = ossClient.calculatePostSignature(postPolicy);

        SignatureDTO signature = new SignatureDTO();
        signature.setAccessId(ossPropertoooies.getAccessKeyId());
        signature.setPolicy(encodedPolicy);
        signature.setSignature(postSignature);
        signature.setFilepath(filepath);
        signature.setHost(host);
        signature.setExpire(fileOssProperties.getUploadSignatureTtl() / 1000);
        signature.setReqFilename(request.getFilename());

接入起来还是非常简单的,一个后端签名,前端上传前后分离的文件上传就已经完成了。这里我们使用postman模拟下前端上传,当然这里可以改为前端使用ajax,或者其他方式都可以。上传的url是由我们自己申请的bucketnameendpoint组成的
在这里插入图片描述
但是其实这里面也是有许多坑的我们还是需要稍微注意下。

带宽限制

上传和下载都会有带宽的限制,如果我们是采用外网直传到阿里云oss的话,需要注意下我们的外网带宽是否够用,以及应对大文件的上传是不是会把带宽打满。如果带宽被打满我们上传就gg了。同样的下载也有带宽限制的,需要避免大文件的下载,如果遇到这种大文件下载我们可以采用其他的方式,比如使用oss的客户端。所以我们需要合理的考虑我们服务器的带宽。如果我们的应用直接是部署在阿里云上面的话,我们可以采用内网的上传和下载。这样的话就不会有带宽的限制。

API使用需要注意点

当我们使用OSSclient提供的一些api使用的时候需要仔细去看看里面是怎么实现的,或者看看它的文档有没有特殊交代的。
比如使用OSSclient提供的processObject方法我们最后需要关闭输入流,如果流不关闭,链接不被释放。应用链接马上就会被占满,然后服务就会成为一个假死的状态,这个问题我们在生产环境就遇到一次。如下图所示线程一直没有被释放。
在这里插入图片描述
像这种为什么需要我们手动去关闭流,为什么不直接api帮我们关闭,阿里云的回复是因为这里返回的流可能业务方自己需要复制、或者读什么的。所以需要调用方主动关闭下,在这个很隐秘的文档中我们也有找到这个答案。
在这里插入图片描述

结束

文章来源:博客园

原文链接:https://www.cnblogs.com/root429/p/15961411.html

分类:
请先登录,再评论

暂无回复,快来写下第一个回复吧~

为你推荐

一次 Node.js http 连接无法复用的问题排查
一次压测中阿里云 SLB 的并发连接数被打满了,导致服务之间的 HTTP 调用延迟很大。当时 SLB 的并发连接数情况如下图所示。登录容器终端查看,发现某个前端 Node.js 服务中的单个容器的 E
webpack5优化实战
本文围绕webpack优化进行讲述,其中也会作某些原理性地解释,尽量做到让大家知道为什么这么做,以及这么做的结果是什么。
前端性能基础:健康网站的关键指标有哪些?
概览 #Web 指标是 Google 开创的一项新计划,旨在为网络质量信号提供统一指导,这些信号对于提供出色的网络用户体验至关重要。多年来,Google 提供了许多性能测量和性能报告工具。一些开发者对这些工具的使用十分在行,而另一些开发者则发现大量的工具和指标令人应接不暇。网站所有者要想了解他
Lighthouse 如何计算网站的整体性能得分?
从为什么分数会波动,它是如何组成的,以及 Lighthouse 如何对每个单独的指标进行评分三部分来介绍lighthouse。
核心web指标对业务的影响
您是否正在努力说服您的利益相关者采用核心 Web 指标? 或者您想知道它是否真的对您的业务有帮助? 本文将通过探索已经对其用户和业务产生积极影响的公司示例,帮助您了解核心 Web 指标如何与关键业务指标相关联。为什么核心 Web 指标对您的用户和业务很重要?组织中的不同利益相关者可以有不同的优先
Largest Contentful Paint 最大内容绘制 (LCP)
最大内容绘制 (LCP) 是测量感知加载速度的一个以用户为中心的重要指标,因为该项指标会在页面的主要内容基本加载完成时,在页面加载时间轴中标记出相应的点,迅捷的 LCP 有助于让用户确信页面是有效的。长久以来,对于网页开发者来说,测量网页主要内容的加载速度和内容对用户的显示速度一直是一个挑战。诸