背景:
我们是一个文件存储和下载的服务,部署架构如下。域名------>VIP------>[同一台机器]nginx,->实际服务。
现象:
在浏览器上下载文件时,打开Chrome的下载页面,发现下载到5M的时候,浏览器就会自动再次从新下载,经过几次后就下载失败。
查看日志:
查看服务的日志,发现报错如下:
http-nio-1601-exec-47 ERROR - 2021-05-25 11:14:51.888 com.xxx.FileController::downloadPartFile -- downloadPartFile
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:356) ~[catalina.jar:8.5.32]
at org.apache.catalina.connector.OutputBuffer.appendByteArray(OutputBuffer.java:795) ~[catalina.jar:8.5.32]
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:724) ~[catalina.jar:8.5.32]
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:391) ~[catalina.jar:8.5.32]
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:369) ~[catalina.jar:8.5.32]
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96) ~[catalina.jar:8.5.32]
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89) ~[catalina.jar:8.5.32]
at org.springframework.util.StreamUtils.copy(StreamUtils.java:89) ~[spring-core-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at com.xxx.HttpUtils.getFileStreamHttp(HttpUtils.java:849) ~[classes/:?]
at com.xxx.FileController.downloadPartFile(FileController.java:687) [classes/:?]
at sun.reflect.GeneratedMethodAccessor54.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_91]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) [spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) [spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) [spring-webmvc-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777) [spring-webmvc-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706) [spring-webmvc-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) [spring-webmvc-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) [spring-webmvc-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) [spring-webmvc-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) [spring-webmvc-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) [spring-webmvc-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) [servlet-api.jar:?]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) [spring-webmvc-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [servlet-api.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [catalina.jar:8.5.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.32]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) [spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.32]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-websocket.jar:8.5.32]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.32]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) [spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.3.RELEASE.jar:4.1.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.32]
at com.xxx.XXXSecurityFilter.doFilter(XXXSecurityFilter.java:23) [security-filter-mini-0.1.8.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.32]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [catalina.jar:8.5.32]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [catalina.jar:8.5.32]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [catalina.jar:8.5.32]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [catalina.jar:8.5.32]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [catalina.jar:8.5.32]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [catalina.jar:8.5.32]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [catalina.jar:8.5.32]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) [tomcat-coyote.jar:8.5.32]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-coyote.jar:8.5.32]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800) [tomcat-coyote.jar:8.5.32]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471) [tomcat-coyote.jar:8.5.32]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:8.5.32]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_91]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.5.32]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_91]
Caused by: java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.write0(Native Method) ~[?:1.8.0_91]
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) ~[?:1.8.0_91]
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) ~[?:1.8.0_91]
at sun.nio.ch.IOUtil.write(IOUtil.java:65) ~[?:1.8.0_91]
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471) ~[?:1.8.0_91]
at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:134) ~[tomcat-coyote.jar:8.5.32]
at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101) ~[tomcat-coyote.jar:8.5.32]
at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:157) ~[tomcat-coyote.jar:8.5.32]
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1279) ~[tomcat-coyote.jar:8.5.32]
at org.apache.tomcat.util.net.SocketWrapperBase.doWrite(SocketWrapperBase.java:670) ~[tomcat-coyote.jar:8.5.32]
at org.apache.tomcat.util.net.SocketWrapperBase.writeBlocking(SocketWrapperBase.java:450) ~[tomcat-coyote.jar:8.5.32]
at org.apache.tomcat.util.net.SocketWrapperBase.write(SocketWrapperBase.java:388) ~[tomcat-coyote.jar:8.5.32]
at org.apache.coyote.http11.Http11OutputBuffer$SocketOutputBuffer.doWrite(Http11OutputBuffer.java:623) ~[tomcat-coyote.jar:8.5.32]
at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:116) ~[tomcat-coyote.jar:8.5.32]
at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:225) ~[tomcat-coyote.jar:8.5.32]
at org.apache.coyote.Response.doWrite(Response.java:541) ~[tomcat-coyote.jar:8.5.32]
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:351) ~[catalina.jar:8.5.32]
... 57 more然后在看nginx的错误日志,截取部分
2021/05/25 11:50:40 [warn] 81423#0: *189 an upstream response is buffered to a temporary file /dev/shm/nginx_temp/proxy/2/01/0000000012 while reading upstream, ...
2021/05/25 11:50:42 [crit] 81423#0: *189 pwrite() "/dev/shm/nginx_temp/proxy/2/01/0000000012" failed (28: No space left on device) while reading upstream, ....先试着调了跟proxy_buffer有关的一些参数,下载还是不行。
后来直接把proxy_buffering关了,重启nginx,下载ok。
未解之谜:
根据nginx的报错日志,检查/dev/shm/nginx_temp/proxy,发现是64M,可以大小也是64M,难道是下载的文件的分片比这个大造成的?但是看后台日志,每一片的大小是5M,这里还是没搞明白到底是什么原因。
有看见文章的朋友,可以给指导一下。
参考:
https://segmentfault.com/a/1190000015921504
版权声明:本文为shuipinglp原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。