2010-09-23 15 views
5

La aplicación, cuando está sujeta a carga, a veces, utiliza el 100%.Hilos de Apache Tomcat en estado EN ESPERA con uso de CPU 100%

haciendo un kill -quit <pid> mostraron más de 1100 hilos en estado de espera como:

Full thread dump Java HotSpot(TM) 64-Bit Server VM (16.3-b01 mixed mode): 

"http-8080-1198" daemon prio=10 tid=0x00007f17b465c800 nid=0x2061 in Object.wait() [0x00007f1762b6e000] 
    java.lang.Thread.State: WAITING (on object monitor) 
     at java.lang.Object.wait(Native Method) 
     - waiting on <0x00007f17cb087890> (a org.apache.tomcat.util.net.JIoEndpoint$Worker) 
     at java.lang.Object.wait(Object.java:485) 
     at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:458) 
     - locked <0x00007f17cb087890> (a org.apache.tomcat.util.net.JIoEndpoint$Worker) 
     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:484) 
     at java.lang.Thread.run(Thread.java:619) 

"http-8080-1197" daemon prio=10 tid=0x00007f17b465a800 nid=0x2060 in Object.wait() [0x00007f1762c6f000] 
    java.lang.Thread.State: WAITING (on object monitor) 
     at java.lang.Object.wait(Native Method) 
     - waiting on <0x00007f17cb14f460> (a org.apache.tomcat.util.net.JIoEndpoint$Worker) 
     at java.lang.Object.wait(Object.java:485) 
     at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:458) 
     - locked <0x00007f17cb14f460> (a org.apache.tomcat.util.net.JIoEndpoint$Worker) 
     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:484) 
     at java.lang.Thread.run(Thread.java:619) 
............ 

El estado no cambia incluso cuando el contexto de aplicación es no desplegada O el DB se reinicia.

Por favor, sugiera una causa probable.

servidor de aplicaciones: Apache Tomcat 6.0.26

Max Temas: 1500

Temas en el estado de espera: 1138

Respuesta

4

"esperando en" no es un problema . El hilo está esperando para ser notificado - y en este caso está bloqueado en el JIoEndpoint.Worker

el hilo de fondo que escucha las conexiones entrantes TCP/IP y las manos a retirarse a un procesador apropiado.

así que creo que se espera de las peticiones reales vienen en.

En primer lugar, la utilización de CPU en realidad aumenta cuando se tiene muchos hilos due to high amount of context switching. ¿De verdad necesitas 1500? ¿Puedes intentar reduciendo?

En segundo lugar, ¿es acaso memoria o GC-ing demasiado a menudo?

"esperando para" sería un problema si los ves. ¿Tiene BLOQUEADO (en el monitor de objetos) o esperando para bloquear() en el seguimiento de la pila?

+0

Estamos cargando la prueba con 7500 usuarios concurrentes. ¿Hay un estadio para ninguna relación de hilos a concurrencia? –

+3

@Mohit: la prueba de carga es la forma correcta de hacerlo. Depende de cuánto tiempo tarda cada solicitud por usuario y qué procesamiento suelen hacer. http://people.apache.org/~mturk/docs/article/ftwai.html says * Para aprovechar al máximo Tomcat, debe limitar el número de solicitudes simultáneas a 200 por CPU. * – JoseK

+0

7500 concurrentes ** usuarios o solicitudes ** - eso es bastante, ¿así que están agrupados? – JoseK

0

En un sistema Solaris puede utilizar el comando

prstat -L -p <pid> 0 1 > filename.txt 

esto le dará un desglose de cada proceso de hacer el trabajo en la CPU y se basará en el ID del procesador de peso ligero, en lugar del PID . Cuando mira el volcado de hilo, puede hacer coincidir el proceso de peso ligero hasta su NID (o TID según las implementaciones) que se muestran en la línea superior del volcado de hilo. Al combinar estas dos cosas, podrás saber cuáles de tus hilos son los de la CPU.

Aquí hay un ejemplo de la salida.

PID USERNAME SIZE RSS STATE PRI NICE  TIME CPU PROCESS/LWPID 
    687 user  1024M 891M sleep 59 0 0:40:07 12.0% java/5 
    687 user  1024M 891M sleep 59 0 0:34:43 15.3% java/4 
    687 user  1024M 891M sleep 59 0 0:17:00 7.6% java/3 
    687 user  1024M 891M sleep 59 0 1:00:07 31.4% java/2 

Luego, con un vertedero de rosca correspondiente, se pueden encontrar estos hilos

"GC task thread#0 (ParallelGC)" prio=3 tid=0x00065295 nid=0x2 runnable 
"GC task thread#1 (ParallelGC)" prio=3 tid=0x00nid=0x3 runnable 
"GC task thread#2 (ParallelGC)" prio=3 tid=0x0009a765 nid=0x4 runnable 
"GC task thread#3 (ParallelGC)" prio=3 tid=0x0003456b nid=0x5 runnable 

Así, en el caso de este caso de alta de la CPU, el problema estaba en la recolección de basura.Esto se ve al hacer coincidir el nid con el campo LWPID

Si esto lo ayuda, sugeriría hacer una secuencia de comandos que tomará la salida de su prstat y el uso de la CPU de una vez. Esto le proporcionará la representación más precisa de su aplicación.

Según los dos hilos originales, @joseK era correcto. Esos hilos están sentados y esperando recibir una solicitud de un usuario. No hay problema allí.

+0

Thx, lo probará para diagnosticarlo aún más. –

Cuestiones relacionadas