Configuración:
Fedora 8
Apache 2.2.8
Tomcat 5.5.8
Apache está reenviando solicitudes utilizando AJP.
Problema:
después de un cierto período de tiempo (no constante en absoluto, puede ser entre una hora o dos, o uno o más días) Tomcat bajará. O deja de responder o pone el genérico 'Servicio temporalmente no disponible'.
Diagnóstico:
hay dos servidores con la misma configuración. Uno alberga un sitio web de mayor tráfico (varias solicitudes por segundo), el otro uno de bajo tráfico (un puñado de solicitudes cada pocos minutos). Ambos sitios web son bases de código completamente diferentes, pero presentan problemas similares.
En el primer servidor, cuando se produce el problema, todos los subprocesos comienzan a tomarse lentamente hasta alcanzar el límite (MaxThreads 200). En ese momento, el servidor ya no responde (y aparece la página de servicio no disponible después de un largo período de tiempo).
En el segundo servidor, cuando se produce el problema, las solicitudes tardan mucho tiempo y cuando se realizan, todo lo que ve es la página de servicio no disponible.
Aparte de la mención del problema MaxThreads, los registros de Tomcat no indican ningún problema específico que pueda estar causando esto.
Sin embargo, en los registros de Apache estamos viendo mensajes aleatorios que se refieren a AJP. Aquí hay una muestra de mensaje aleatorio que vemos (sin un orden específico):
[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)
La otra cosa extraña que hemos notado en el servidor de mayor tráfico es que justo antes de que el problema comience a suceder, las consultas a la base de datos tardan mucho más que antes (2000-5000 ms en comparación con normalmente 5-50ms). Esto solo dura de 2 a 4 segundos antes de que aparezca el mensaje MaxThreads. Supongo que esto es el resultado del servidor que de repente trata con demasiados datos / tráfico / hilos.
Información básica:
estos dos servidores han estado funcionando sin problemas durante bastante tiempo. En realidad, los sistemas se configuraron utilizando dos NIC durante ese tiempo. Separaron el tráfico interno y externo. Después de una actualización de red, cambiamos estos servidores a NIC individuales (esto nos lo recomendaron por razones de seguridad / simplicidad). Después de ese cambio, los servidores comenzaron a tener estos problemas.
Resolución:
la solución obvia sería volver a una configuración de dos NIC. Los problemas con eso son que causaría algunas complicaciones con la configuración de la red, y parece ignorar el problema. Preferiríamos probar y ejecutarlo en una sola configuración de NIC.
Buscar en Google los diversos mensajes de error no proporcionó nada útil (ya sea soluciones antiguas o no relacionadas con nuestro problema).
Intentamos ajustar los diversos tiempos de espera, pero eso solo hizo que el servidor se ejecutara un poco más antes de morir.
No estamos seguros de dónde buscar para diagnosticar más el problema. Todavía nos estamos aferrando a los popotes sobre cuál podría ser el problema:
1) La configuración con AJP y Tomcat es incorrecta u obsoleta (es decir, ¿errores conocidos?)
2) La configuración de la red (dos NIC versus una NIC) está causando confusión o problemas de rendimiento.
3) Los sitios web en sí (no hay código común, no se utilizan plataformas, solo código Java básico con servlets y JSP)
Actualización 1:
Siguiendo los consejos útiles de David Pashley, hice un volcado de seguimiento / subproceso de pila durante el problema. Lo que encontré fue que los 200 hilos estaban en uno de los siguientes 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, solo uno de los 200 hilos estaba en este 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]
Es posible que el controlador de Oracle en este hilo esté obligando a todos los otros hilos a esperar a que se complete. Por alguna razón, debe estar atascado en este estado de lectura (el servidor nunca se recupera solo, requiere un reinicio).
Esto sugiere que debe estar relacionado con la red entre el servidor y la base de datos, o con la base de datos misma. Continuamos los esfuerzos de diagnóstico, pero cualquier consejo sería útil.