現場反饋,一個導出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