文件上传把服务搞崩了?

点击上方“Java金融”,选择“设为星标”

后台回复"888"获取bat面试题集

引言

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

oss 文件上传

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

Web端上传

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

  • 上传慢:用户数据需先上传到应用服务器,之后再上传到OSS,网络传输时间比直传到OSS多一倍。如果用户数据不通过应用服务器中转,而是直传到OSS,速度将大大提升。而且OSS采用BGP带宽,能保证各地各运营商之间的传输速度。

  • 扩展性差:如果后续用户数量逐渐增加,则应用服务器会成为瓶颈。本来就已经采用了OSS上传了,然后还要在占用自己服务器。

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

JavaScript客户端签名直传

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

服务端签名后直传

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

如何接入
引入依赖
  • 因为本人是从事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列?这种情况也不是没有可能的。

服务端构建签名

89f4c05b77e0423fbc3ccb9eda7300a6.png上图是官网提供的入门例子,代码是一大坨,我们可以看看稍微优化后的代码:创建一个单例的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组成的4332455444b0e5f3936f7f13985e2e81.png但是其实这里面也是有许多坑的我们还是需要稍微注意下。

带宽限制

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

API使用需要注意点

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

结束

  • 由于自己才疏学浅,难免会有纰漏,假如你发现了错误的地方,还望留言给我指出来,我会对其加以修正。

  • 如果你觉得文章还不错,你的转发、分享、赞赏、点赞、留言就是对我最大的鼓励。

  • 感谢您的阅读,十分欢迎并感谢您的关注。站在巨人的肩膀上摘苹果: https://help.aliyun.com/document_detail/31924.html https://gosspublic.alicdn.com/AliyunJavaSDK/3.10.2/javadoc/index.html?spm=a2c4g.11186623.0.0.14c240c20nrAKm

往期精选

PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
文件服务器规划设计 文件服务器规划设计 密级:公开 文件上传服务器 FUS(file upload service) 概要设计 项目编号 文档版本号 2011-12-19 归属部门 归属项目 编写人 编写日期 中航国际金网公司 文件服务器规划设计全文共29页,当前为第1页。技术部 文件服务器规划设计全文共29页,当前为第1页。 版本历史 日期 版本 简要描述信息 作者 2011-12-19 创建该文档 高正 2012-1-09 修改部分内容 高正 2012-01-11 结构进行了调整 高正 2012-1-16 评审后初步定稿 高正 分发清单 文档接收者 组织部门 文件服务器规划设计全文共29页,当前为第2页。目 录 文件服务器规划设计全文共29页,当前为第2页。 文件服务器规划设计全文共29页,当前为第3页。 文件服务器规划设计全文共29页,当前为第3页。 文件服务器规划设计全文共29页,当前为第4页。 前言 文件服务器规划设计全文共29页,当前为第4页。 编写目的 编写该文件的目的是描述文件服务器的框架概要设计,有如下好处: 确定系统开发功能的范围。 供设计人员分析时使用。 运维人员在进行部署时的参考。 作为软件开发人员进行设计和编码的基础。 确定系统测试及验收内容。 软件维护的参考资料。 作为项目验收标准之一。 适用范围 业务或需求分析人员、架构设计师、软件开发工程师、测试人员、项目管理人员。 项目概述 背景 文件服务器规划设计全文共29页,当前为第5页。对于Web服务器来说,不管是Apache、IIS还是其他容器,图片是最消耗资源的,于是我们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服务器,甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务系统压力,并且可以保证系统不会因为图片问题而溃,在应用服务器和图片服务器上,可以进行不同的配置优化,比如apache在配置ContentType的时候可以尽量少支持,尽可能少的LoadModule,保证更高的系统消耗和执行效率。 文件服务器规划设计全文共29页,当前为第5页。 同时,对于某些应用需要针对某图片进行截取不同尺寸的图片,以节省网络带宽。例如产品图片,往往要提供多个缩略图,例如在列表页为小图,在产品详情页为中图,当鼠标放到中图上再显示大图等。为此上传服务器需要提供图片的适当裁剪成大中小各种尺寸的图片,以适应多种情况。 其实,不只是图片耗网络带宽,一切需要下载的文件同样存在着网络带宽的耗用文件。 基于以上原因,金网公司开发了文件上传服务器,作为所有新建项目上传图片、文件的统一存放地。为以后的集群、负载均衡等分布式架构提供一定的基础。 目标 文件服务器规划设计全文共29页,当前为第6页。开发文件上传服务器应用程序,对外提供文件上传服务。通过各种参数的设定来完成图片裁剪、图片转换、是否多文件存储等功能,并将文件路径反馈给任务发起方。目前暂不提供图片生成水印功能。 文件服务器规划设计全文共29页,当前为第6页。 同时开辟后台,可以创建应用、查看图片日志,如所有已上传文件的来源地、日期等信息。 概要设计 工作模式 FUS文件服务器可对N台Web应用服务器提供文件上传服务,Web应用服务器中部署了"文件上传组件"。 FUS文件服务器分为两个部分:FUS Service服务器(简称FUS Server)和文件存储服务器(简称Storage Server)。FUS Server负责为其他Web应用提供上传文件和记录功能,所上传文件被真实地存储在了Storage Server上。Storage Server既作为物理存储服务器,同时为各个Web应用提供所存储文件的外链功能。即:在Web应用上可通过链接的方式访问所存储的文件。 Web应用服务器与文件服务器的交互过程基本上由4步来完成: 第一步:设定FUSConfig各种参数,确定上传模式 Web应用服务器中,文件上传组件[即fus文件夹]需要被放入到根目录下。同时,需要上传文件的页面中,进行配置,构造各种参数。具体参见应用端配置部分。 第二步:用户点击上传按钮 文件服务器规划设计全文共29页,当前为第7页。由于第一步所设置的参数的不同,本步骤的展现形式也不同,主要分为以下两种情况: 文件服务器规划设计全文共29页,当前为第7页。 情况一:弹出文件选择窗口 情况二:弹出多选文件选择窗口 第三步:上传文件 该步骤为根据文件上传组件自动构造参数,将文件上传到FUS Server中。FUS Server接收到传来的文件信息和各种参数后,将文件转存到指定的Storage Server中,并将日志记录到数据库。 第四步:将文件上传后的路径返回到客户端 文件上传组件会把文件真实路径反馈到客户端。 【第

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值