
De repente, estamos vendo um erro intermitente, mas muito frequente, ao fazer POST de arquivos em um servlet Tomcat por meio de https por meio de um proxy reverso do servidor Apache. O erro parece ocorrer apenas durante o POST de arquivos de 20 MB ou mais (vídeos). Não vimos problema com arquivos menores de 2 a 5 MB (JPEGs).
O erro ocorre em dois dos cinco servidores em que testamos.
No lado do servidor da conexão, ou seja, um servlet Tomcat construído usando Jersey, obtemos:
java.net.SocketException: Connection reset
O servidor Apache na mesma máquina, agindo como proxy reverso, fornece esta mensagem de erro:
[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 ()
Definir o nível de log do servidor Apache para depurar e reproduzir o problema não produz informações adicionais - ainda recebemos a mesma mensagem de erro sem nenhuma mensagem associada.
Com um pouco menos de frequência, não obtemos uma exceção no lado do Tomcat, mas verificar o número de bytes transferidos em relação ao cabeçalho Content-Length revela que nem tudo passou. O erro no servidor Apache neste segundo cenário é o mesmo do primeiro "proxy: falha no corpo da solicitação de passagem..."
A versão do servidor Apache é 2.2.15.29 em um servidor e 2.2.15.30 no outro, rodando no CentOS 6.2 em todos os casos. As regras do proxy reverso são configuradas da seguinte forma:
<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>
Observe que a passagem do proxy passa apenas por http, não por https.
Estamos usando certificados autoassinados para a configuração SSL. A versão do OpenSSL é 1.0.1e-fips em um dos servidores com falha e 1.0.0-fips no outro.
No lado do Tomcat, estamos executando o 7.0.26 e usando o Jersey 1.8.
Duvido que isso importe, mas a conexão do navegador de origem do POST é o Firefox 27 ou o Chrome 34.
Em um caso, nosso servlet foi atualizado recentemente, embora o código para lidar com uploads de arquivos não tenha mudado recentemente. No outro servidor com problema, estamos executando uma compilação de servlet de meses atrás. Na verdade, nessa segunda máquina, não temos conhecimento de nenhuma alteração de código ou configuração nos últimos meses – ela ficou ociosa desde meados de fevereiro até hoje.
O que devo fazer a seguir para solucionar esse problema? Para onde devo procurar?
-- Atualizar --
Testes adicionais mostram que a conexão às vezes é interrompida mesmo se eu ignorar o servidor Apache e o POST diretamente para o Tomcat. Portanto, não parece ser um problema de proxy.
- Mais atualizações -
Estamos vendo problemas intermitentemente ao copiar os mesmos arquivos grandes via scp. Parece que o problema subjacente é o firewall entre nossa sub-rede de escritório/desenvolvimento e a rede de produção/teste. A mensagem de erro quando uma cópia do scp falha é "Tubo quebrado".
Aqui está o rastreamento de pilha do servlet quando a conexão cai:
16/05/2014 13:20:44,566 [http-bio-8080-exec-7] ERRO com.objectvideo.wx.casemanager.service.resources.QueryFileService [null] - Falha ao carregar arquivo(s). javax.ws.rs.WebApplicationException: java.net.SocketException: Conexão redefinida em com.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadRawFile(QueryFileService.java:342) em com.objectvideo.wx.casemanager.service. resources.QueryFileService.uploadFile (QueryFileService.java:607) em sun.reflect.GeneratedMethodAccessor37.invoke (fonte desconhecida) em sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) em java.lang.reflect.Method.invoke ( Method.java:606) em com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) em com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch (AbstractResourceMethodDispatchProvider.java:205) em com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) em com.sun.jersey.server.impl.uri.rules.HttpMethodRule .accept(HttpMethodRule.java:288) em com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) em com.sun.jersey.server.impl.uri.rules.RightHandPathRule .accept(RightHandPathRule.java:147) em com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) em com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest (WebApplicationImpl.java:1469) em com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400) em com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java :1349) em com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339) em com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) em com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) em com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699) em javax.servlet. http.HttpServlet.service(HttpServlet.java:722) em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) em org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) em org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) em org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.java:472) em org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) em org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) em org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) em org.apache.catalina.core.StandardEngineValve .invoke(StandardEngineValve.java:118) em org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) em org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987) em org. apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579) em org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307) em java.util.concurrent.ThreadPoolExecutor.runWorker( ThreadPoolExecutor.java:1145) em java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) em java.lang.Thread.run(Thread.java:724) Causado por: java.net.SocketException: Conexão redefinir em java.net.SocketInputStream.read(SocketInputStream.java:189) em java.net.SocketInputStream.read(SocketInputStream.java:121) em org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:532) em org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501) em org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563) em org.apache.coyote.http11.filters .IdentityInputFilter.doRead(IdentityInputFilter.java:118) em org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326) em org.apache.coyote.Request.doRead(Request.java:422) em org. apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290) em org.apache.tomcat.util.buf.ByteChunk.substtract(ByteChunk.java:431) em org.apache.catalina.connector.InputBuffer.read( InputBuffer.java:315) em org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:167) em org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1719) em org.apache.commons .io.IOUtils.copyLarge(IOUtils.java:1696) em org.apache.commons.io.IOUtils.copy(IOUtils.java:1671) em org.apache.commons.io.FileUtils.copyInputStreamToFile(FileUtils.java:1444 ) em com.objectvideo.wx.casemanager.service.resources.QueryFileService.writeTempFile(QueryFileService.java:535) em com.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadRawFile(QueryFileService.java:320) ... mais 35process(AbstractHttp11Processor.java:987) em org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579) em org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307) em java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) em java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) em java.lang.Thread.run(Thread.java:724 ) Causado por: java.net.SocketException: Redefinição de conexão em java.net.SocketInputStream.read(SocketInputStream.java:189) em java.net.SocketInputStream.read(SocketInputStream.java:121) em org.apache.coyote.http11 .InternalInputBuffer.fill(InternalInputBuffer.java:532) em org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501) em org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563 ) em org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:118) em org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326) em org.apache.coyote.Request. doRead(Request.java:422) em org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290) em org.apache.tomcat.util.buf.ByteChunk.substtract(ByteChunk.java:431) em org .apache.catalina.connector.InputBuffer.read(InputBuffer.java:315) em org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:167) em org.apache.commons.io.IOUtils.copyLarge(IOUtils .java:1719) em org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1696) em org.apache.commons.io.IOUtils.copy(IOUtils.java:1671) em org.apache.commons. io.FileUtils.copyInputStreamToFile(FileUtils.java:1444) em com.objectvideo.wx.casemanager.service.resources.QueryFileService.writeTempFile(QueryFileService.java:535) em com.objectvideo.wx.casemanager.service.resources.QueryFileService. uploadRawFile(QueryFileService.java:320) ... mais 35process(AbstractHttp11Processor.java:987) em org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579) em org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307) em java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) em java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) em java.lang.Thread.run(Thread.java:724 ) Causado por: java.net.SocketException: Redefinição de conexão em java.net.SocketInputStream.read(SocketInputStream.java:189) em java.net.SocketInputStream.read(SocketInputStream.java:121) em org.apache.coyote.http11 .InternalInputBuffer.fill(InternalInputBuffer.java:532) em org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501) em org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563 ) em org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:118) em org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326) em org.apache.coyote.Request. doRead(Request.java:422) em org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290) em org.apache.tomcat.util.buf.ByteChunk.substtract(ByteChunk.java:431) em org .apache.catalina.connector.InputBuffer.read(InputBuffer.java:315) em org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:167) em org.apache.commons.io.IOUtils.copyLarge(IOUtils .java:1719) em org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1696) em org.apache.commons.io.IOUtils.copy(IOUtils.java:1671) em org.apache.commons. io.FileUtils.copyInputStreamToFile(FileUtils.java:1444) em com.objectvideo.wx.casemanager.service.resources.QueryFileService.writeTempFile(QueryFileService.java:535) em com.objectvideo.wx.casemanager.service.resources.QueryFileService. uploadRawFile(QueryFileService.java:320) ... mais 35fill(InternalInputBuffer.java:501) em org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563) em org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:118) em org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326) em org.apache.coyote.Request.doRead(Request.java:422) em org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer .java:290) em org.apache.tomcat.util.buf.ByteChunk.substtract(ByteChunk.java:431) em org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:315) em org.apache. catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:167) em org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1719) em org.apache.commons.io.IOUtils.copyLarge(IOUtils.java: 1696) em org.apache.commons.io.IOUtils.copy(IOUtils.java:1671) em org.apache.commons.io.FileUtils.copyInputStreamToFile(FileUtils.java:1444) em com.objectvideo.wx.casemanager.service .resources.QueryFileService.writeTempFile(QueryFileService.java:535) em com.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadRawFile(QueryFileService.java:320) ... 35 maisfill(InternalInputBuffer.java:501) em org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563) em org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:118) em org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:326) em org.apache.coyote.Request.doRead(Request.java:422) em org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer .java:290) em org.apache.tomcat.util.buf.ByteChunk.substtract(ByteChunk.java:431) em org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:315) em org.apache. catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:167) em org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1719) em org.apache.commons.io.IOUtils.copyLarge(IOUtils.java: 1696) em org.apache.commons.io.IOUtils.copy(IOUtils.java:1671) em org.apache.commons.io.FileUtils.copyInputStreamToFile(FileUtils.java:1444) em com.objectvideo.wx.casemanager.service .resources.QueryFileService.writeTempFile(QueryFileService.java:535) em com.objectvideo.wx.casemanager.service.resources.QueryFileService.uploadRawFile(QueryFileService.java:320) ... 35 mais
Responder1
Tente anexar keepalive=on
às suas ProxyPass
diretivas.
Isso também pode exigir KeepAlive
a configuração no lado do servidor Apache global.on