Installazione:
Fedora 8
Apache 2.2.8
Tomcat 5.5.8
Apache inoltra le richieste usando AJP.
Problema:
dopo un certo periodo di tempo (nessuna costante, può essere compresa tra un'ora o due o uno o più giorni), Tomcat scenderà. O smette di rispondere o inserisce il generico "Servizio temporaneamente non disponibile".
Diagnosi:
esistono due server con la stessa configurazione. Uno ospita un sito Web a traffico più elevato (diverse richieste al secondo), l'altro uno a basso traffico (una manciata di richieste ogni pochi minuti). Entrambi i siti Web sono basi di codice completamente diverse, ma presentano problemi simili.
Sul primo server, quando si verifica il problema, tutti i thread iniziano lentamente a essere ripresi fino a raggiungere il limite (MaxThreads 200). A quel punto il server non risponde più (e viene visualizzata la pagina di servizio non disponibile dopo un lungo periodo di tempo).
Sul secondo server, quando si verifica il problema, le richieste impiegano molto tempo e quando vengono eseguite, viene visualizzata solo la pagina del servizio non disponibile.
Oltre alla menzione del problema MaxThreads, i registri Tomcat non indicano alcun problema specifico che potrebbe causare questo.
Tuttavia, nei registri di Apache vediamo messaggi casuali che si riferiscono ad AJP. Ecco un esempio di messaggio casuale che vediamo (in nessun ordine specifico):
[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)
L'altra cosa strana che abbiamo notato sul server a traffico più elevato è che proprio prima che si verifichi il problema, le query del database impiegano molto più tempo rispetto a prima (2000-5000 ms contro normalmente 5-50ms). Questo dura solo 2-4 secondi prima che appaia il messaggio MaxThreads. Suppongo che questo sia il risultato del server che improvvisamente ha a che fare con troppi dati / traffico / thread.
Informazioni di base:
Questi due server erano in esecuzione senza problemi da un po 'di tempo. I sistemi sono stati effettivamente installati ciascuno utilizzando due schede di rete durante quel periodo. Hanno separato il traffico interno ed esterno. Dopo un aggiornamento della rete, abbiamo spostato questi server in singole NIC (questo ci è stato consigliato per motivi di sicurezza / semplicità). Dopo tale modifica, i server hanno iniziato ad avere questi problemi.
Risoluzione:
la soluzione ovvia sarebbe quella di tornare a una configurazione di due schede di rete. Il problema è che ciò comporterebbe alcune complicazioni con la configurazione della rete e sembra ignorare il problema. Preferiremmo provare a farlo funzionare su una singola configurazione della scheda di rete.
Cercare su Google i vari messaggi di errore non ha fornito nulla di utile (soluzioni vecchie o non correlate al nostro problema).
Abbiamo provato a regolare i vari timeout, ma ciò ha reso il server leggermente più lungo prima di morire.
Non siamo sicuri di dove cercare per diagnosticare ulteriormente il problema. Stiamo ancora cercando di capire quale potrebbe essere il problema:
1) L'impostazione con AJP e Tomcat non è corretta o è obsoleta (ad esempio, bug noti?)
2) L'impostazione della rete (due NIC contro una NIC) sta causando problemi di confusione o velocità effettiva.
3) I siti Web stessi (non esiste un codice comune, nessuna piattaforma utilizzata, solo codice Java di base con servlet e JSP)
Aggiornamento 1:
seguendo i consigli utili di David Pashley, ho fatto un dump dello stack / thread dello stack durante il problema. Quello che ho scoperto è che tutti i 200 thread erano in uno dei seguenti stati:
"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, solo un thread su tutti i 200 thread era in questo stato:
"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]
È possibile che il driver Oracle in questo thread stia forzando tutti gli altri thread ad attendere il completamento. Per qualche motivo deve essere bloccato in questo stato di lettura (il server non ripristina mai da solo, richiede un riavvio).
Ciò suggerisce che deve essere correlato alla rete tra il server e il database o al database stesso. Stiamo continuando gli sforzi di diagnosi, ma qualsiasi suggerimento sarebbe utile.