Apache + Tomcat tendo problemas de comunicação. Mensagens de erro pouco claras Derrubando sites hospedados no Tomcat

21

Configuração:
Fedora 8
Apache 2.2.8
Tomcat 5,5,8
O Apache está encaminhando solicitações usando o AJP.

Problema:
Depois de um certo período de tempo (sem constante, pode ser entre uma ou duas horas, ou um ou mais dias), o Tomcat irá para baixo. Ele pára de responder ou coloca o 'Serviço temporariamente indisponível' genérico.

Diagnóstico:
Existem dois servidores com a mesma configuração. Um abriga um site de tráfego maior (várias solicitações por segundo), o outro um tráfego baixo (um punhado de solicitações a cada poucos minutos). Ambos os websites são bases de código completamente diferentes, mas exibem problemas semelhantes.

No primeiro servidor, quando o problema ocorre, todos os threads começam lentamente a ser ocupados até atingir o limite (MaxThreads 200). Nesse ponto, o servidor não está mais respondendo (e exibe a página de serviço indisponível após um longo período de tempo).

No segundo servidor, quando o problema ocorre, os pedidos demoram muito tempo e, quando terminam, tudo o que você vê é a página de serviço indisponível.

Além da menção ao problema do MaxThreads, os logs do Tomcat não indicam problemas específicos que poderiam estar causando isso.

No entanto, nos logs do Apache, estamos vendo mensagens aleatórias referentes ao AJP. Aqui está uma amostra de mensagem aleatória que vemos (em nenhuma ordem específica):

[error] (70007)The timeout specified has expired: ajp_ilink_receive() can't receive header
[error] (104)Connection reset by peer: ajp_ilink_receive() can't receive header
[error] proxy: AJP: disabled connection for (localhost)
[error] ajp_read_header: ajp_ilink_receive failed
[error] (120006)APR does not understand this error code: proxy: read response failed from 127.0.0.1:8009 (localhost)
[error] ap_proxy_connect_backend disabling worker for (localhost)

A outra coisa estranha que notamos no servidor de tráfego mais alto é que logo antes de o problema começar a acontecer, as consultas de banco de dados estão demorando muito mais tempo do que antes (2000-5000 ms versus normalmente 5-50ms). Isso dura apenas 2 a 4 segundos antes que a mensagem MaxThreads apareça. Eu estou supondo que este é um resultado do servidor de repente, lidando com muitos dados / tráfego / threads.

Informações básicas:
Esses dois servidores estavam funcionando sem problemas há algum tempo. Na verdade, os sistemas foram configurados usando dois NICs durante esse período. Eles separaram o tráfego interno e externo. Após uma atualização de rede, movemos esses servidores para NICs individuais (isso foi recomendado para nós por motivos de segurança / simplicidade). Depois dessa mudança, os servidores começaram a ter esses problemas.

Resolução:
A solução óbvia seria voltar para uma configuração de dois NICs. Os problemas com isso são que isso causaria algumas complicações com a configuração da rede e parece ignorar o problema. Preferimos tentar executá-lo em uma única configuração de NIC.

Pesquisando as várias mensagens de erro não forneceu nada de útil (soluções antigas ou não relacionadas ao nosso problema).

Tentamos ajustar os vários tempos limites, mas isso fez com que o servidor funcionasse um pouco mais antes de morrer.

Não temos certeza de onde procurar para diagnosticar o problema ainda mais. Ainda estamos nos agarrando ao que o problema poderia ser:

1) A configuração com o AJP e o Tomcat está incorreta ou desatualizada (ou seja, erros conhecidos?)
2) A configuração da rede (dois NICs versus um NIC) está causando problemas de confusão ou taxa de transferência. 3) Os sites em si (não há código comum, nenhuma plataforma sendo usada, apenas código Java básico com servlets e JSP)

Atualização 1:
Seguindo o conselho útil de David Pashley, fiz um despejo de rastreamento / thread de pilha durante o problema. O que eu descobri foi que todos os 200 segmentos estavam em um dos seguintes estados:

"TP-Processor200" daemon prio=1 tid=0x73a4dbf0 nid=0x70dd waiting for monitor entry [0x6d3ef000..0x6d3efeb0]
at  oracle.jdbc.pool.OracleConnectionCacheImpl.getActiveSize(OracleConnectionCacheImpl.java:988)
- waiting to lock <0x7e3455a0> (a oracle.jdbc.pool.OracleConnectionCacheImpl)
[further stack trace removed for brevity]

"TP-Processor3" daemon prio=1 tid=0x08f142a8 nid=0x652a waiting for monitor entry [0x75c7d000..0x75c7ddb0]
at oracle.jdbc.pool.OracleConnectionCacheImpl.getConnection(OracleConnectionCacheImpl.java:268)
- waiting to lock <0x7e3455a0> (a oracle.jdbc.pool.OracleConnectionCacheImpl)
[further stack trace removed for brevity]

Curiosamente, apenas um segmento de todos os 200 segmentos estava neste estado:

"TP-Processor2" daemon prio=1 tid=0x08f135a8 nid=0x6529 runnable [0x75cfe000..0x75cfef30]
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at oracle.net.ns.Packet.receive(Unknown Source)
at oracle.net.ns.DataPacket.receive(Unknown Source)
at oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)
at oracle.net.ns.NetInputStream.read(Unknown Source)
at oracle.net.ns.NetInputStream.read(Unknown Source)
at oracle.net.ns.NetInputStream.read(Unknown Source)
[further stack trace removed for brevity]

Pode ser que o driver Oracle neste encadeamento esteja forçando todos os outros encadeamentos a aguardarem a conclusão. Por alguma razão, é preciso estar preso neste estado de leitura (o servidor nunca se recupera sozinho, requer uma reinicialização).

Isso sugere que ele deve estar relacionado à rede entre o servidor e o banco de dados ou o próprio banco de dados. Estamos continuando os esforços de diagnóstico, mas qualquer sugestão seria útil.

    
por Jordy Boom 04.06.2009 / 20:40

7 respostas

9

Acontece que esta versão (classes12 - bastante antiga) do driver Oracle tinha vários bugs que causavam um deadlock (como visto no estado TP-Processor2 citado acima). Não se tornou ativo até que mudamos para o novo ambiente. A atualização para a versão mais recente (ojdbc14) resolveu o problema no servidor principal.

    
por 10.06.2009 / 16:36
6

A partir da descrição, eu sugiro que o problema pode ser devido às consultas do banco de dados que estão demorando muito. Se as consultas demorarem mais, a solicitação demorará mais e, portanto, você terá mais delas em execução de uma só vez. Como você está vendo, você está ficando sem threads de tomcat. Quando você resolve o problema com o banco de dados, você deve estar bem.

  • Obtenha um rastreamento de pilha, usando jstack ou usando kill -3 $ process_id. Veja o que seus tópicos estão fazendo quando morre. Se todos estão esperando no banco de dados, isso é um bom indicador para minha teoria. Eles podem estar todos esperando em algum bloqueio.
  • Instale o LambdaProbe. É inestimável para descobrir o que seu gato está fazendo.
  • Atualize seu tomcat. 5.5.8 é incrivelmente antigo. Eu acho que eles estão agora no 5.5.27.
por 05.06.2009 / 10:32
5

Adicione connectionTimeout e keepAliveTimeout ao seu conector AJP localizado em /etc/tomcat7/server.xml.

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" 
           connectionTimeout="10000" keepAliveTimeout="10000" />

Informações sobre o conector AJP no link

  • connectionTimeout = O número de milissegundos que este Conector aguardará, depois de aceitar uma conexão, para que a linha de URI de solicitação seja apresentada. O valor padrão para os conectores do protocolo AJP é -1 (isto é, infinito).

  • keepAliveTimeout = O número de milissegundos que este Conector aguardará por outra solicitação AJP antes de fechar a conexão. O valor padrão é usar o valor que foi definido para o atributo connectionTimeout.

Se os valores connectionTimeout e keepAliveTimeout não estiverem definidos, as conexões AJP serão mantidas ativas por infinito. Causando muitos threads, os threads máximos padrão são 200.

Eu recomendo instalar o psi-probe - um gerenciador e monitor avançado para o Apache Tomcat, bifurcado do Lambda Probe. link

    
por 13.07.2014 / 18:12
4

Devido ao modo como o AJP funciona, as conexões persistentes entre o apache (usando mod_proxy_ajp ou mod_jk) podem ser fechadas com segurança pelo cliente . Nesse caso, o cliente é o funcionário do apache que é aberto e, em seguida, mantém uma conexão com o tomcat para a vida do processo de trabalho .

Devido a esse comportamento, você não pode ter mais funcionários do apache do que os segmentos de trabalho do tomcat. Isso fará com que funcionários http adicionais não consigam se conectar ao tomcat (pois a fila de aceitação está cheia) e marcará seu back-end como DOWN!

    
por 10.06.2009 / 16:46
2

Eu tive melhores resultados com mod_proxy em vez de mod_ajp em termos de estabilidade, então tente essa solução. Não é invasivo - na melhor das hipóteses resolve o problema e na pior das hipóteses descarta o mod_ajp.

Além disso, parece que seus Tomcats param de responder e todos os threads de solicitação estão comprometidos. Peça à sua equipe de desenvolvimento que analise o que está acontecendo - realizando um despejo de thread e entregá-lo a eles. útil.

    
por 04.06.2009 / 22:01
1

A primeira coisa que penso quando ouço que um servidor é executado por um tempo, de repente fica mais lento e, em seguida, começa a ter falhas de serviço é que está ficando sem RAM e trocando swap. Não estou claro se os fracassos do AJP que você está vendo podem ser conseqüentes aos tempos limite, mas isso não parece completamente irracional; não vejo nenhuma maneira óbvia de conectar-se à NIC, no entanto. De qualquer forma, recomendo que você tenha uma ideia do que está acontecendo com o uso da memória quando esses eventos ocorrem.

Se você está ficando sem memória RAM, pode ser necessário desativar seu Apache MaxClients e aumentar seu ListenBacklog .

A propósito, obrigado por fazer sua pergunta tão bem organizada e completa.

    
por 04.06.2009 / 21:54
1

Eu tive erros de log semelhantes no ambiente Redhat com proxy_ajp e Tomcat. Resolvido atualizando o pacote httpd:

yum update httpd

de:

  • link
  • link

para:

  • link
  • link

Em seguida, reinicie o apache, seguido pelo reinício do Tomcat.

Isso resolveu para mim!

    
por 07.05.2013 / 21:12