如何解决 Apache 服务器反向代理断开连接的问题?

如何解决 Apache 服务器反向代理断开连接的问题?

我们突然发现,在通过 Apache Server 反向代理通过 https 将文件发布到 Tomcat servlet 时,出现了一个间歇性但非常频繁的错误。该错误似乎仅在发布 20 MB 或更大的文件(视频)时发生。我们没有看到 2 到 5 MB 的较小文件(JPEG)出现问题。

我们尝试了五台服务器,其中两台出现了这个错误。

在连接的服务器端,即使用 Jersey 构建的 Tomcat servlet,我们得到:

java.net.SocketException: Connection reset

同一台机器上的 Apache 服务器作为反向代理,给出了以下错误消息:

[Thu May 15 17:08:58 2014] [error] proxy: pass request body failed to 127.0.0.1:8080 (localhost) from 192.168.16.xx ()

将 Apache 服务器的日志记录级别设置为调试并重现问题不会产生任何附加信息 - 我们仍然会收到相同的错误消息而没有任何关联消息。

不太常见的是,我们在 Tomcat 端没有收到异常,但检查传输的字节数与 Content-Length 标头后发现并非所有内容都已传输。第二种情况下 Apache Server 中的错误与第一种“代理:传递请求主体失败...”中的错误相同。

一台服务器上的 Apache Server 版本为 2.2.15.29,另一台服务器上的 Apache Server 版本为 2.2.15.30,均在 CentOS 6.2 下运行。反向代理规则设置如下:

<IfModule mod_proxy.c>
        ProxyRequests Off

    # Case Manager Tomcat web service
        ProxyPass /casemanager http://localhost:8080/casemanager
        ProxyPassReverse /casemanager http://localhost:8080/casemanager

    # Matcher images directories
        ProxyPass /matcher-images http://x.x.x.108:80/matcher-images
</IfModule>

请注意,代理直通只是通过 http,而不是 https。

我们使用自签名证书进行 SSL 配置。在一台发生故障的服务器上,OpenSSL 版本为 1.0.1e-fips,在另一台服务器上,OpenSSL 版本为 1.0.0-fips。

在 Tomcat 方面,我们运行 7.0.26 并使用 Jersey 1.8。

我怀疑这很重要,但 POST 源自的浏览器连接是 Firefox 27 或 Chrome 34。

有一次,我们的 servlet 最近更新了,但处理文件上传的代码最近没有更改。在遇到问题的另一台服务器上,我们运行的是几个月前构建的 servlet。事实上,在第二台机器上,我们不知道过去几个月有任何代码或配置更改——从二月中旬到今天,它一直处于闲置状态。

我下一步该怎么做才能解决此问题?我应该去哪里查找?

- 更新 -

进一步的测试表明,即使我绕过 Apache 服务器并直接向 Tomcat 发送 POST,连接有时也会断开。因此,这似乎根本不是代理问题。

-- 进一步更新 --

我们偶尔会发现通过 scp 复制相同大型文件时出现问题。看来根本问题是我们的办公室/开发子网与生产/暂存网络之间的防火墙。scp 复制失败时出现的错误消息是“管道损坏”。

以下是连接断开时 servlet 的堆栈跟踪:

2014-05-16 13:20:44,566 [http-bio-8080-exec-7] 错误 com.objectvideo.wx.casemanager.service.resources.QueryFileService [null] - 无法上传文件。 javax.ws.rs.WebApplicationException:java.net.SocketException:连接重置,位于 com.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadRawFile(QueryFileService.java:342),位于 com.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadFile(QueryFileService.java:607),位于 sun.reflect.GeneratedMethodAccessor37.invoke(未知来源),位于 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43),位于 java.lang.reflect.Method.invoke(Method.java:606),位于 com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60),位于com.sun.jersey.server.impl.model.method.dispatch.Abs​​tractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205) at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288) at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339) at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)位于 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) 在 org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) 在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987) 在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579) 在org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:724) 导致:java.net.SocketException:连接重置 at java.net.SocketInputStream.read(SocketInputStream.java:189) at java.net.SocketInputStream.read(SocketInputStream.java:121) at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:532) at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501) at org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563) at org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:118) at org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326) at org.apache.coyote.Request.doRead(Request.java:422) at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290) at org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:431) at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:315) at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:167) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1719) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1696) at org.apache.commons.io.IOUtils.copy(IOUtils.java:1671) at org.apache.commons.io.FileUtils.copyInputStreamToFile(FileUtils.java:1444) at com.objectvideo.wx.casemanager.service.resources.QueryFileService.writeTempFile(QueryFileService.java:535) at com.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadRawFile(QueryFileService.java:320)... 另外 35 个process(AbstractHttp11Processor.java:987) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:724) 导致:java.net.SocketException:连接重置 at java.net.SocketInputStream.read(SocketInputStream.java:189) at java.net.SocketInputStream.read(SocketInputStream.java:121) at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:532) at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501) at org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563) at org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:118) at org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326) at org.apache.coyote.Request.doRead(Request.java:422) at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290) at org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:431) at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:315) at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:167) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1719) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1696) at org.apache.commons.io.IOUtils.copy(IOUtils.java:1671) at org.apache.commons.io.FileUtils.copyInputStreamToFile(FileUtils.java:1444) at com.objectvideo.wx.casemanager.service.resources.QueryFileService.writeTempFile(QueryFileService.java:535) at com.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadRawFile(QueryFileService.java:320) ... 另外 35 个process(AbstractHttp11Processor.java:987) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:724) 导致:java.net.SocketException:连接重置 at java.net.SocketInputStream.read(SocketInputStream.java:189) at java.net.SocketInputStream.read(SocketInputStream.java:121) at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:532) at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501) at org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563) at org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:118) at org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326) at org.apache.coyote.Request.doRead(Request.java:422) at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290) at org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:431) at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:315) at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:167) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1719) at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1696) at org.apache.commons.io.IOUtils.copy(IOUtils.java:1671) at org.apache.commons.io.FileUtils.copyInputStreamToFile(FileUtils.java:1444) at com.objectvideo.wx.casemanager.service.resources.QueryFileService.writeTempFile(QueryFileService.java:535) at com.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadRawFile(QueryFileService.java:320) ... 另外 35 个填充(InternalInputBuffer.java:501)在 org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563)在 org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:118)在 org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326)在 org.apache.coyote.Request.doRead(Request.java:422)在 org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290)在 org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:431)在 org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:315)在org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:167) 在 org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1719) 在 org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1696) 在 org.apache.commons.io.IOUtils.copy(IOUtils.java:1671) 在 org.apache.commons.io.FileUtils.copyInputStreamToFile(FileUtils.java:1444) 在 com.objectvideo.wx.casemanager.service.resources.QueryFileService.writeTempFile(QueryFileService.java:535) 在 com.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadRawFile(QueryFileService.java:320) ... 35 更多的填充(InternalInputBuffer.java:501)在 org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563)在 org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:118)在 org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326)在 org.apache.coyote.Request.doRead(Request.java:422)在 org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290)在 org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:431)在 org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:315)在org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:167) 在 org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1719) 在 org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1696) 在 org.apache.commons.io.IOUtils.copy(IOUtils.java:1671) 在 org.apache.commons.io.FileUtils.copyInputStreamToFile(FileUtils.java:1444) 在 com.objectvideo.wx.casemanager.service.resources.QueryFileService.writeTempFile(QueryFileService.java:535) 在 com.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadRawFile(QueryFileService.java:320) ... 35 更多的

答案1

尝试附加keepalive=on到您的ProxyPass指令。

这可能需要在全局 Apache 服务器端也KeepAlive进行设置。on

相关内容