Configuração:
Fedora 8
Apache 2.2.8 O
Tomcat 5.5.8
Apache está encaminhando solicitações usando o AJP.
Problema:
Após um determinado período de tempo (nenhuma constante, pode ocorrer entre uma hora ou duas ou um ou mais dias) o Tomcat será desativado. Ele para de responder ou coloca o genérico 'Serviço temporariamente indisponível'.
Diagnóstico:
Existem dois servidores com a mesma configuração. Um abriga um site de tráfego mais alto (várias solicitações por segundo) e o outro, um de baixo tráfego (um punhado de solicitações a cada poucos minutos). Ambos os sites são bases de código completamente diferentes, mas apresentam problemas semelhantes.
No primeiro servidor, quando o problema ocorre, todos os threads começam a ser ocupados lentamente até atingir o limite (MaxThreads 200). Nesse ponto, o servidor não está mais respondendo (e aparece com a página de serviço indisponível após um longo período de tempo).
No segundo servidor, quando o problema ocorre, as solicitações demoram muito tempo e, quando concluídas, tudo o que você vê é a página de serviço indisponível.
Além da menção ao problema MaxThreads, os logs do Tomcat não indicam nenhum problema específico que possa estar causando isso.
No entanto, nos logs do Apache, estamos vendo mensagens aleatórias referentes ao AJP. Aqui está um exemplo de mensagem aleatória que vemos (sem 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, imediatamente antes do problema começar, as consultas ao banco de dados estão demorando muito mais do que antes (2000-5000 ms versus normalmente 5-50ms). Isso dura apenas 2-4 segundos antes que a mensagem MaxThreads seja exibida. Estou assumindo que isso é resultado do servidor de repente lidar com muitos dados / tráfego / threads.
Informações de plano de fundo:
Esses dois servidores estavam em execução sem problemas há algum tempo. Os sistemas foram realmente configurados, cada um usando duas placas de rede durante esse período. Eles separaram o tráfego interno e o externo. Após uma atualização de rede, movemos esses servidores para NICs únicas (isso nos foi recomendado por motivos de segurança / simplicidade). Após essa alteração, os servidores começaram a ter esses problemas.
Resolução:
a solução óbvia seria retornar à configuração de duas NICs. Os problemas com isso são que isso causaria algumas complicações na configuração da rede e parece ignorar o problema. Preferimos tentar executá-lo em uma única configuração de NIC.
Pesquisar as várias mensagens de erro no Google não forneceu nada de útil (soluções antigas ou não relacionadas ao nosso problema).
Tentamos ajustar os vários tempos limite, mas isso fez com que o servidor funcionasse um pouco mais antes de morrer.
Não temos certeza de onde procurar para diagnosticar mais o problema. Ainda estamos tentando entender qual seria o problema:
1) A configuração com o AJP e o Tomcat está incorreta ou desatualizada (ou seja, erros conhecidos?)
2) A configuração da rede (duas NICs versus uma 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 descobri foi que todos os 200 threads 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 thread de todos os 200 threads 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 aguardar a conclusão. Por alguma razão, ele deve estar preso nesse estado de leitura (o servidor nunca se recupera sozinho, é necessário reiniciar).
Isso sugere que ele deve estar relacionado à rede entre o servidor e o banco de dados ou ao próprio banco de dados. Continuamos os esforços de diagnóstico, mas qualquer dica seria útil.