Configuration:
Fedora 8
Apache 2.2.8
Tomcat 5.5.8
Apache transfère les demandes à l'aide d'AJP.
Problème:
après un certain laps de temps (pas de constante du tout, cela peut prendre entre une heure ou deux, ou un ou plusieurs jours) Tomcat va tomber. Soit il cesse de répondre, soit il met en place le «service temporairement indisponible» générique.
Diagnostic:
Il y a deux serveurs avec la même configuration. L'un héberge un site Web à plus fort trafic (plusieurs demandes par seconde), l'autre un site à faible trafic (une poignée de demandes toutes les quelques minutes). Les deux sites Web sont des bases de code complètement différentes, mais ils présentent des problèmes similaires.
Sur le premier serveur, lorsque le problème se produit, tous les threads commencent lentement à être utilisés jusqu'à ce qu'il atteigne la limite (MaxThreads 200). À ce stade, le serveur ne répond plus (et propose la page de service indisponible après une longue période).
Sur le deuxième serveur, lorsque le problème se produit, les demandes prennent beaucoup de temps et lorsqu'elles sont terminées, tout ce que vous voyez est la page de service indisponible.
Mis à part la mention du problème MaxThreads, les journaux Tomcat n'indiquent aucun problème spécifique pouvant être à l'origine de ce problème.
Cependant, dans les journaux Apache, nous voyons des messages aléatoires faisant référence à AJP. Voici un échantillon de message aléatoire que nous voyons (dans aucun ordre spécifique):
[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'autre chose étrange que nous avons remarquée sur le serveur à trafic plus élevé est que juste avant le début du problème, les requêtes de base de données prennent beaucoup plus de temps qu'auparavant (2000-5000 ms contre normalement 5-50ms). Cela ne dure que 2 à 4 secondes avant l'apparition du message MaxThreads. Je suppose que cela est dû au fait que le serveur traite soudainement trop de données / trafic / threads.
Informations générales:
Ces deux serveurs fonctionnaient sans problème depuis un certain temps. Les systèmes ont en fait été configurés chacun à l'aide de deux cartes réseau pendant cette période. Ils ont séparé le trafic interne et externe. Après une mise à niveau du réseau, nous avons déplacé ces serveurs vers des cartes réseau uniques (cela nous a été recommandé pour des raisons de sécurité / simplicité). Après ce changement, les serveurs ont commencé à avoir ces problèmes.
Résolution:
La solution évidente serait de revenir à une configuration de deux cartes réseau. Les problèmes avec cela sont que cela entraînerait des complications avec la configuration du réseau, et cela semble ignorer le problème. Nous préférons essayer de le faire fonctionner sur une seule configuration de carte réseau.
La recherche sur les différents messages d'erreur n'a fourni rien d'utile (que ce soit d'anciennes solutions ou sans rapport avec notre problème).
Nous avons essayé d'ajuster les différents délais d'attente, mais cela a simplement fait fonctionner le serveur un peu plus longtemps avant de mourir.
Nous ne savons pas où chercher pour diagnostiquer davantage le problème. Nous essayons toujours de comprendre quel pourrait être le problème:
1) La configuration avec AJP et Tomcat est incorrecte ou obsolète (c.-à-d. Des bogues connus?)
2) La configuration du réseau (deux cartes réseau contre une carte réseau) cause de la confusion ou des problèmes de débit.
3) Les sites Web eux-mêmes (il n'y a pas de code commun, pas de plates-formes utilisées, juste du code Java de base avec des servlets et JSP)
Mise à jour 1:
suite aux conseils utiles de David Pashley, j'ai effectué un vidage de trace / thread de pile pendant le problème. Ce que j'ai trouvé, c'est que les 200 threads étaient dans l'un des états suivants:
"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]
Curieusement, un seul thread sur les 200 threads était dans cet état:
"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]
Il se peut que le pilote Oracle de ce thread force tous les autres threads à attendre qu'il se termine. Pour une raison quelconque, il doit être bloqué dans cet état de lecture (le serveur ne récupère jamais seul, il nécessite un redémarrage).
Cela suggère qu'il doit être lié soit au réseau entre le serveur et la base de données, soit à la base de données elle-même. Nous poursuivons nos efforts de diagnostic, mais tout conseil serait utile.