记一次阿里云oss文件上传服务假死
引言
记得以前刚开始学习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是由我们自己申请的bucketname和endpoint组成的

但是其实这里面也是有许多坑的我们还是需要稍微注意下。
带宽限制
上传和下载都会有带宽的限制,如果我们是采用外网直传到阿里云oss的话,需要注意下我们的外网带宽是否够用,以及应对大文件的上传是不是会把带宽打满。如果带宽被打满我们上传就gg了。同样的下载也有带宽限制的,需要避免大文件的下载,如果遇到这种大文件下载我们可以采用其他的方式,比如使用oss的客户端。所以我们需要合理的考虑我们服务器的带宽。如果我们的应用直接是部署在阿里云上面的话,我们可以采用内网的上传和下载。这样的话就不会有带宽的限制。
API使用需要注意点
当我们使用OSSclient提供的一些api使用的时候需要仔细去看看里面是怎么实现的,或者看看它的文档有没有特殊交代的。
比如使用OSSclient提供的processObject方法我们最后需要关闭输入流,如果流不关闭,链接不被释放。应用链接马上就会被占满,然后服务就会成为一个假死的状态,这个问题我们在生产环境就遇到一次。如下图所示线程一直没有被释放。

像这种为什么需要我们手动去关闭流,为什么不直接api帮我们关闭,阿里云的回复是因为这里返回的流可能业务方自己需要复制、或者读什么的。所以需要调用方主动关闭下,在这个很隐秘的文档中我们也有找到这个答案。

结束
- 由于自己才疏学浅,难免会有纰漏,假如你发现了错误的地方,还望留言给我指出来,我会对其加以修正。
- 如果你觉得文章还不错,你的转发、分享、赞赏、点赞、留言就是对我最大的鼓励。
- 感谢您的阅读,十分欢迎并感谢您的关注。
站在巨人的肩膀上摘苹果:
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
记一次阿里云oss文件上传服务假死的更多相关文章
- 构建基于阿里云OSS文件上传服务
转载请注明来源:http://blog.csdn.net/loongshawn/article/details/50710132 <构建基于阿里云OSS文件上传服务> <构建基于OS ...
- PHP实现阿里云OSS文件上传(支持批量)
上传文件至阿里云OSS,整体逻辑是,文件先临时上传到本地,然后在上传到OSS,最后删除本地的临时文件(也可以不删,具体看自己的业务需求),具体实现流程如下: 1.下载阿里云OSS对象上传SDK(P ...
- SpringBoot整合阿里云OSS文件上传、下载、查看、删除
1. 开发前准备 1.1 前置知识 java基础以及SpringBoot简单基础知识即可. 1.2 环境参数 开发工具:IDEA 基础环境:Maven+JDK8 所用技术:SpringBoot.lom ...
- php阿里云oss文件上传
php的文件上传 文件上传 php的文件上传放在了$_FILES数组里,单文件和多文件上传的区别在于$_FILES['userfile']['name']是否为数组, 不熟悉的可以读一下官方文档 单文 ...
- 阿里云OSS文件上传封装
1.先用composer安装阿里云OSS的PHPSDK 2.配置文件里定义阿里云OSS的秘钥 3.在index控制器里的代码封装 <?php namespace app\index\contro ...
- 记录-阿里云Oss文件上传
public class OssUtil { /** * 上传图片 * @param file * @param request * @return */ public static Map<S ...
- Thinkphp整合阿里云OSS图片上传实例
Thinkphp3.2整合阿里云OSS图片上传实例,图片上传至OSS可减少服务器压力,节省宽带,安全又稳定,阿里云OSS对于做负载均衡非常方便,不用传到各个服务器了 首先引入阿里云OSS类库 < ...
- SpringBoot完美配置阿里云的文件上传
新建一个config类 AliyunOSS.java @Configuration @Data public class AliyunOSS { private OSSClient ossClient ...
- 阿里云OSS图片上传类
1.阿里云基本函数 /** * 把本地变量的内容到文件 * 简单上传,上传指定变量的内存值作为object的内容 */ public function putObject($imgPath,$obje ...
随机推荐
- 如何在Xamarin中快速集成Android版认证服务-手机号码篇
Xamarin作为微软提供的移动服务多系统开发平台,成为很多开发者首选的应用开发平台.AppGallery Connect(以下简称AGC)也在逐步的支持Xamarin的SDK.认证服务也是支持Xam ...
- jsp中获取下拉框的value问题
遇到问题 最近快期末考试了,今天想写一个简单的增删改查项目练练手,可是在刚写增加的时候就出现了问题,"增"一直是最简单的操作,本来自付很快就能写完,可是数据库中对应的下拉框数据一直 ...
- TCP可靠性
目录 一:TCP可靠性 1.通过序列号与确认应答提高可靠性 一:TCP可靠性 简介 TCP 通过检验和.序列号.确认应答.重发控制.连接管理以及窗口控制等机制实现可靠性传输. 1.通过序列号与确认应答 ...
- 软件版本GA、Beta、RC含义
Alpha:是内部测试版,一般不向外部发布,会有很多Bug.一般只有测试人员使用.Beta:也是测试版,这个阶段的版本会一直加入新的功能.在Alpha版之后推出.RC:(Release Candida ...
- table 增加或删除一行
转载请注明来源:https://www.cnblogs.com/hookjc/ <HTML><SCRIPT LANGUAGE="JScript">funct ...
- NSMutableString基本概念
1.NSMutableString 基本概念 NSMutableString 类 继承NSString类,那么NSString 供的方法在NSMutableString中基本都可以使用,NSMutab ...
- 这个Dubbo注册中心扩展,有点意思!
今天想和大家聊聊Dubbo源码中实现的一个注册中心扩展.它很特殊,也帮我解决了一个困扰已久的问题,刚刚在生产中用了,效果很好,迫不及待想分享给大家. Dubbo的扩展性非常灵活,可以无侵入源码加载自定 ...
- 配置docker的DNS
方式一:在宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS: { "dns" : [ "114.114.114.114 ...
- appium填坑
首次使用appium web driver,不说搭建环境的麻烦,初次写完一个操作计算器的程序,但是运行一直报错:selenium.common.exceptions.WebDriverExceptio ...
- python小白记录一 ——python脚本生成windows可执行exe
1.需要安装pywin32 先查看自己有没有安装:使用如下命令查看 pip show pywin32 如果没有则用下面方式进行安装: pip install pywin32 然后等待安装完成: 2.再 ...