
Na verdade, estou investigando conexões de longa duração de um aplicativo da Web baseado em Java/Tomcat. Depois de descartar quaisquer motivos internos ou baseados em aplicativos, agora passo para a camada de rede. A razão pela qual estou investigando esse problema é que temos picos aparentemente aleatórios em nosso monitoramento do tempo de resposta. Ao investigar, descobri que esse comportamento não é tão aleatório, mas acionado por determinadas solicitações HTTP do cliente. O que há de especial nessas conexões é que todas elas se originam do mesmo endereço IP e parecem usar um Bluecoat Proxy, porque vejo um cabeçalho HTTP x-bluecoat-via.
Como eu disse, a aplicação em si funciona normalmente, apenas o final da conexão (do ponto de vista do Tomcat) parece estar atrasado de alguma forma. O servidor não se comunica diretamente com o cliente, mas está atrás de um Loadbalancer F5 que deve realmente armazenar em cache as respostas (o que pode não acontecer devido a um cabeçalho de identidade de codificação de aceitação e a resposta real ser muito grande para o buffer).
Recebi um dump TCP, devido a um erro infeliz, atualmente só vejo pacotes do LB para o appserver, não os pacotes reais enviados do appserver.
O dump contém diversas solicitações na mesma conexão TCP/IP, devido ao pool de conexões feito pelo F5. A última solicitação HTTP nesta conexão é a conexão real que foi sinalizada como de longa duração (925836,442ms) em nosso registro. O que vejo são os pacotes de solicitação, uma série de ACKs que me levam a acreditar que o appserver está escrevendo sua resposta e finalmente dois pacotes FIN, ACK seguidos por um RST, ACK que é o último pacote enviado pelo F5.
Do ponto de vista do tempo, tudo isso acontece no decorrer de 250 ms, o último pacote é enviado 15 minutos e 13 segundos antes de eu ver o log de resposta no appserver que é escrito após a resposta ser considerada concluída pelo Tomcat.
Estou meio sem ideias no momento e tenho algumas perguntas em aberto:
Existe alguma razão para o Linux manter uma conexão aberta que recebeu um RST e não informar a camada de aplicação?
Existe algum outro tempo limite que possa levar a esse comportamento? Se este fosse o tempo limite de retransmissão do TCP, eu veria mais RSTs do LB.
Alguma outra idéia de por que uma conexão fechada no fio levaria a uma conexão ainda aberta na camada de aplicação?
Como algo que acontece na camada de aplicação (solicitação HTTP especial) pode levar a um comportamento reproduzível na camada de transporte?
Talvez eu esteja completamente no caminho errado e este seja um problema de manutenção de conexão dentro do Tomcat?
Responder1
Eu realmente não posso ajudar na camada de rede, mas no Tomcat existem vários lugares onde você pode configurar issohttp://tomcat.apache.org/connectors-doc/reference/workers.html. Você pode tentar substituir o tempo limite e configurá-lo para encerrar a conexão após um determinado período de tempo.
No link você também tem configurações de balanceador de carga que podem ser úteis em seu cenário.