如何解決 Apache Server 反向代理程式斷開連線的問題?

如何解決 Apache Server 反向代理程式斷開連線的問題?

當透過 Apache 伺服器反向代理透過 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 伺服器版本為 2.2.15.29,另一台伺服器上的 Apache 伺服器版本為 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。事實上,在第二台機器上,我們不知道過去幾個月有任何程式碼或設定變更——它從 2 月中旬到今天一直閒置。

接下來我該做什麼來解決這個問題?我該去哪裡找?

- 更新 -

進一步的測試表明,即使我繞過 Apache Server 並直接 POST 到 Tomcat,連線有時也會被斷開。所以這似乎根本不是代理問題。

-- 進一步更新 --

我們間歇性地發現透過 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.servicewx.casager.servicewx.casager.servicewx.casager.servicewx.casager.servicewx.casager.servicewx. 。 ( Method.java:606) 在com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) 在com.sun.jersey.server.impl.model.method.dispatch.Abs​​tractResourceMethodDispatchvidvider $ResponseOutInvoker._dispatch (AbstractResourceMethodDispatchProvider.java:205) 在com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) 在.java:75). .rules.HttpMethodRule .accept(HttpMethodRule.java:288) 在com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) 在com.sun.jersey.server.impl.uri 。 .WebApplicationImpl._handleRequest (WebApplicationImpl.java:1469) 在com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400) 在com.sun.jersey.server.L. (WebApplicationImpl.java :1349)在com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.Webjava:1339)在com.sun.jersey.spi.container.servlet.Webjava:1339)在com.sun.jersey.spi.container.servlet.Webjava:1339)在com.sun.javaservice(WebComponent.java. :416)在com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) 位於com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699) 位於位於javax.servlet。 java:210)在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) 在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) 在org.apache.catalina.apacheatorator .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.Standard:927) 在 org.apache.AccessLogalina.Standard. .invoke(StandardEngineValve.java:118) 在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) 在org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHtt177) 在Pt. apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579) 在org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307) 在java.utpoint$SocketProcessor.run(JIoEndpoint.java:307) 在java.util.concurrentor.T.Wutil. ThreadPoolExecutor.java:1145) 在java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 在java.lang.Thread.run(Thread.java:724) 引起:java.net.SocketException:連接在java.net.SocketInputStream.read(SocketInputStream.java:189) 處重置在java.net.SocketInputStream.read(SocketInputStream.java:121) 在org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.Rjava: 532) 處重置在org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501) 在org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563) 在. coyote.http11.filters .IdentityInputFilter.doRead(IdentityInputFilter.java:118) 在org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326) 在org.apache.coyote.Request.java. 422) 在org. apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290) 在org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:431) 在org.apache. .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.copyInputStreams.copyInputTo FileUtils.java:1444) )在com.objectvideo.wx.casemanager.service.resources.QueryFileService.writeTempFile(QueryFileService.java:535)在com.objectvideo.wx.casemanager.service.resources.QueryFileServicecom.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadRawFile(QueryFileerel. :320)...還有35個進程(AbstractHttp11Processor.java:987)在org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)在org.apache.tomcat.util.net.JIoEndpoint$Sock:579)在org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIapache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIapache.在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 在java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 在java.Thlang.Thjava.TThread. ) )引起:java.net.SocketException:在org.apache.coyote.http11的java.net.SocketInputStream.read(SocketInputStream.java:189)的java.net.SocketInputStream.read(SocketInputStream.java:121)處重置連接.InternalInputBuffer.fill(InternalInputBuffer.java:532) 在org.apache.coyote.http11.InternalInputBuffer.fill(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 .Request。 ) 在org .apache.catalina.connector.InputBuffer.read(InputBuffer.java:315) 在org.apache.catalina.connector.CoyoteInputStream.readIO(CoyoteInputStream.java:167) 在org.apache.commons.io.readIO(CoyoteInputStream.java:167) 在org.apache.commons.io.readIOUtils. 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。 .QueryFileService。進程(AbstractHttp11Processor.java:987)在org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)在org.apache.tomcat.util.net.JIoEndpoint$Sock:579)在org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIapache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIapache.在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 在java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 在java.Thlang.Thjava.TThread. ) )引起:java.net.SocketException:在org.apache.coyote.http11的java.net.SocketInputStream.read(SocketInputStream.java:189)的java.net.SocketInputStream.read(SocketInputStream.java:121)處連接重置.InternalInputBuffer.fill(InternalInputBuffer.java:532) 在org.apache.coyote.http11.InternalInputBuffer.fill(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 .Request。 ) 在org .apache.catalina.connector.InputBuffer.read(InputBuffer.java:315) 在org.apache.catalina.connector.CoyoteInputStream.readIO(CoyoteInputStream.java:167) 在org.apache.commons.io.readIO(CoyoteInputStream.java:167) 在org.apache.commons.io.readIOUtils. 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。 .QueryFileService。填入(InternalInputBuffer.java:501)在org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563)在org.apache.coyote.http11.filters.IdentityInput185ter(Fil在org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326) 在org.apache.coyote.Request.doRead(Request.java:422) 在org.apache.catalina.connector.InputBuffer.realReadytes(InputBytes(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.IOUtilIOUtils.java:1719)在org.apache.commons.io.IOUtilIOs.copyLarge( :第 1696 章.resources.QueryFileService.writeTempFile(QueryFileService.java:535) at com.objectvideo.wx.casager.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.IdentityInput185ter(Fil在org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326) 在org.apache.coyote.Request.doRead(Request.java:422) 在org.apache.catalina.connector.InputBuffer.realReadytes(InputBytes(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.IOUtilIOUtils.java:1719)在org.apache.commons.io.IOUtilIOs.copyLarge( :第 1696 章.resources.QueryFileService.writeTempFile(QueryFileService.java:535) at com.objectvideo.wx.casager.service.resources.QueryFileService.uploadRawFile(QueryFileService.java:320) ... 35 更多

答案1

嘗試附加keepalive=on到您的ProxyPass指令中。

這可能也需要在全域 Apache 伺服器端KeepAlive進行設定。on

相關內容