tomcat throwing java.net.SocketTimeoutException: null 当应用程序在 elb 后面运行并且响应在 http 上流式传输时
Posted
技术标签:
【中文标题】tomcat throwing java.net.SocketTimeoutException: null 当应用程序在 elb 后面运行并且响应在 http 上流式传输时【英文标题】:tomcat throwing java.net.SocketTimeoutException: null when application running behind elb and response is streamed on http 【发布时间】:2017-07-09 15:59:17 【问题描述】:我在过去几天遇到了一个问题: 我有一个在 elb 后面的 aws ecs 上运行的 Spring Boot 应用程序。 该应用程序暴露了一个正在下载 750 MB 的球衣端点 来自 aws-s3 的分块文件。我们从 s3 获取输入流 在 HTTP 上流式传输。在下载过程中(大约 400 MB 的下载量),我们低于 exception。
Caused by: org.apache.catalina.connector.ClientAbortException:
java.net.SocketTimeoutException
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:380)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:350)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:405)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:393)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96 )
at org.glassfish.jersey.servlet.internal.ResponseWriter$NonCloseableOutputStreamWrapper.write(ResponseWriter.java:325)
at org.glassfish.jersey.message.internal.CommittingOutputStream.write(CommittingOutputStream.java:229)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$UnCloseableOutputStream.write(WriterInterceptorExecutor.java:299)Caused by: java.net.SocketTimeoutException: null
at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:134)
at org.apache.tomcat.util.net.NioselectorPool.write(NioSelectorPool.java:157)
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1221)
at org.apache.tomcat.util.net.SocketWrapperBase.writeBlocking(SocketWrapperBase.java:378)
at org.apache.tomcat.util.net.SocketWrapperBase.write(SocketWrapperBase.java:347) at org.apache.coyote.http11.Http11OutputBuffer$SocketOutputBuffer.doWrite(Http11OutputBuffer.java:561)
at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:112)
我对此进行了研究,并在谷歌上发现了一些常见的解决方案,表明要保持:elb
的空闲时间为更高的值,并将 tomcat 的keepalivetimeout
设置为更高的值,当我将这两个属性都设置为 1800 时,它开始了工作,但我不想将这些值设置为不:不了解根本原因。
另外,我进入 tomcat 类并找到了引发异常的实际代码行,但仍然无法找出原因。
另外,无法理解为什么只有在应用程序运行时才会发生这种情况 在 aws-elb 后面。 有没有人有这方面的线索?
【问题讨论】:
【参考方案1】:我遇到了与您类似的问题,让我尝试解释问题的根本原因: 数据流来自“Spring Boot Application”-->ELB-->Client。“Spring Boot Application”和ELB在同一个网络,所以它们之间的网速非常快。但是ELB和Client之间的网速并没有那么快。 让我们假设如果ELB内存缓冲区和网络缓冲区被数据填满,因为数据没有及时传输到客户端,会发生什么情况:会抛出SocketTimeoutException,因为微小的4k字节无法在“ timeout”秒,因为没有足够的空间来接受来自“Spring Boot Application”的数据(应该立即完成)。 所以我的猜测是,如果超时时间足够小或者ELB和客户端之间的网络速度足够慢,问题总是会发生。
【讨论】:
您可以通过调用 sleep 来模拟慢速客户端,然后尝试根据新的 keepalivetimeout 参数重现错误。我的猜测是该错误再次发生。以上是关于tomcat throwing java.net.SocketTimeoutException: null 当应用程序在 elb 后面运行并且响应在 http 上流式传输时的主要内容,如果未能解决你的问题,请参考以下文章
tomcat报错:java.net.ConnectException:Connection refused
带有球衣的嵌入式 tomcat 上的 java.net.SocketTimeoutException
Tomcat停止时报错(java.net.ConnectException: 拒绝连接 (Connection refused))
tomcat报java.net.UnknownHostException
java.net.SocketException:Spring Hibernate Tomcat 打开的文件太多
在centos6中部署tomcat项目,但是总报java.net.ConnectException: Connection refused