现场反馈,一个导出zip压缩包的下载功能,卡住847M不动了,滚动条不断提示,但速度为0,用的chrome浏览器。经,询问,另外一个导出100多M的文件正常。
首先在家里进行了测试,模拟了1G的文件进行测试,一切正常。又模拟了2G的文件,显示内存溢出。可是传送文件是经过流传输的,经过apache 的IOUtils.copy复制到 Http Response的OutPutStream,不会占用太大内存。
IOUtils.copy的代码有问题,经查看源码,是按4K缓存写入,没有问题,怀疑排除。
从输出异常栈中发现了ch.qos.logback.access.servlet.TeeServletOutputStream类,该项目使用了logback的access日志,经查看源码,果真是有问题。该类包装了ServletOutputStream,并重写了write(byte byteArray[], int offset, int length) 方法,把数据写入到ServletOutputStream以外,又写入了BtyeArrayOutputStream进行了缓存,用于日志输出。 underlyingStream.write(byteArray, offset, length); baosCopy.write(byteArray, offset, length); 下面是变量定义 final ServletOutputStream underlyingStream; final ByteArrayOutputStream baosCopy;
关闭access日志,暂时没有实施,由于该日志是在parent项目里配置的,因此选择了修改个别代码,用真实的从包装类中获取真实的HttpServletResponse并写出文件流。
解决了内存存溢出出问题,又出现了新的现象,文件超过1G大小就会中断,后台服务tomcat报timeout错误,可是网速好的状况下就没有这个错误。由于使用了nginx代理服务,因此是nginx缓存致使的超时问题,proxy_buffering off;把代理缓存关掉问题解决。nginx
故障总结:chrome