一次文件上传踩坑经历
先说场景
系统已经有一套文件上传的系统,可以支持图片和音频上传:
浏览器端上传文件,到我们的服务器,然后由我们的服务器上传到七牛的服务器。这里面有几个啃爹的设计:
- 我们的服务器分成了两个,一个是业务服务器,一个是文件服务器,上传的文件会先经过业务服务器,转发给文件服务器,最后再上传到七牛服务器
- 服务器不止一台,都用nginx做了负载均衡
- 服务器都是阿里云的
- 开发语言Java,使用的框架是Spring,容器是Resin
不得不说以上看起来是应用场景,但其实每一条都是一个巨大的坑。先不说具体的业务,其实七牛是提供了直接在浏览器端用JS上传文件的功能得,直接调SDK即可,服务器需要做的是保证安全,也就是调用SDK前从服务器获取一个key(这个key里既有安全参数,也包含了上传文件的具体动作和后续的数据处理,JS实际上只需要调用接口就可以)。
但现实是我们现在要添加一个视频上传的功能(包含视频上传到七牛并做后续的转码截图等处理),因为业务紧张,还是走最开始的那套流程,即由服务端实现。
实现
既然要快!那就走快的打法,对七牛来说上传音频和视频接口是一样的,只是转码的接口不一样,即上传后做的数据处理,所以基本上,我把业务服务器的代码拷贝一份,改一下调用的URL,文件服务器的大部分也都拷贝一份,然后在设置转码参数和文件命名的时候单独处理一下就可以了,理论上来说,这样做没有任何问题,毕竟都是文件上传。
问题
测试的时候,一开始没问题啊?!多测几次问题就出现了。一查发现,文件稍微大点服务器就自动重启了,报错信息是JVM outof memory。内存不够!
排查后发现,服务端总是返回502 Bad Gateway或504 Gateway timeout。504就是超时了,超时次数过多nginx认为服务器已经挂了,就返回502
业务上已经限制了文件大小,我也加入到nginx参数中
client_max_body_size 1000M;
但实际情况是,超过40M的文件都有可能超时!
优化及排查
那首先我想到的是
Comments