style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

THREADS EN TOMCAT

Buenas tardes, tengo una situación crítica con una aplicación que está corriendo en Tomcat. El tomcat está corriendo como servidor web en un windows con 4 GB de ram. En los parametro del java los configuré de la siguiente manera.
-Xms512m
-Xmx2g
-XX:PermSize=128m
-XX:MaxPermSize=128m

El tema es que la aplicación está corriendo bien pero llega un momento en que no se puede acceder y se cae la aplicación. Tengo que reiniciar el tomcat para poder que la aplicación levante. Yo utilicé JavaMelody y he podido detectar que los thread al subir casi a 200 thread se caía la aplicación. Lo que hice fue editar el SERVER.XML y aumentar el maxthread de 150 a 300. Pero nuevamente la aplicación subió a 380 threads y se cayó.
Quisiera que me ayudaran que mas puedo configurar para que la aplicación se mantenga estable y los threads no se aumenten o tengan esos picos tan elevados.
SI me pueden orientar se los agradezco.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

memoria

200 threads no me parece excesivo. Ni 400. Yo tengo aplicaciones que usan RMI por ejemplo y cada petición abre un hilo nuevo, pero después de usarse unos 400 hilos se eliminan cuando llega la recolección de basura y se queda otra vez como con 20 o menos.

Más bien revisa si realmente llega a usar los 2GB de RAM que le has asignado, y si los 128MB de PermSize son suficientes.

Si le aumentas hilos y memoria y se sigue cayendo, muy probablemente tienes un problema de fuga de recursos: no estás terminando procesos (por eso se quedan tantos threads corriendo), o no cierras recursos como conexiones a base de datos, archivos, etc.

Imagen de paranoid_android

Soporte de Cluster

Sin duda la tecnología java es escalable precisamente para soportar más carga.

La cuestión es si Tomcat ofrece ese soporte o necesitas un web aplication que si ofrezca estas características.
JBOSS, Glassfish, Websphere, etc.

Posiblemente necesitarás un balanceador y más hardware para distribuir la carga.
Necesitarías evaluar ¿El web aplication elegido soporta instalación en cluster?, ¿Que parámetros te deja configurar?
Ejemplo: máximo numero de sesiones activas

Otro consejo es que los parámetros del sistema no deben estar al máximo ya que si la máquina virtual satura el sistema no podrás dar soporte como por ejemplo aplicar algún parche o efectuar algún respaldo. Tiene que tener cierta holgura en CPU, Memoria, Espacio de swap, etc...

Imagen de ezamudio

cluster?

Cluster para aguantar 400 hilos? Y sí tiene holgura de memoria, está usando tan sólo 2GB de los 4 que tiene el equipo (que hoy en día 4GB no es nada, pero pues para una aplicación que tiene tal vez 400 usuarios concurrentes, debería ser suficiente).

Y estás confundiendo web application con application server. JBoss, tomcat, glassfish, etc son application servers. Ahí puedes hospedar una o varias web applications. También se les conoce como contenedores.

Pero antes de aventarle más hardware así nomás, o de cambiar de contenedor, este cuate debería revisar su aplicación, para ver si no tiene algún problema en su código y por eso se le quedan tantos hilos activos.

memoria

Muchas gracias por su comentario, muy atinados.
Voy hacer la revisión que me indica. Tengo 2 preguntas.
1- Sabe alguna forma de saber cual es el JSP de mi aplicación que mas thread deja abiertos?
2- En JavaMelody veo que hay una gráfica que se llama LOADED CLASSES, siempre esta entre el rango 6k y 7k. Sabe como se interpreta o que significa esto?-
Muchas gracias y saludos.

Imagen de avefenix_x

Comparto la idea de que antes verifique su app.

Los datos no son los suficientes para dar una posible solucion, no se dice el numero de usuario concurrentes que se conectan para determinar que el servidor tiene estres, tampoco se comenta si tienes procesos que accesan a disco(Exportaciones e importaciones). Las respuestas de solucion seran variadas pero no todas acertadas.

El problema mas comun con el gasto de memoria son las implementaciones internas de la app.

Saludos.

Imagen de ezamudio

clases

LOADED CLASSES simplemente son las clases que se han cargado a la JVM. Dado que siempre monitoreas la misma aplicación, es normal que siempre aparezca un número muy similar (aunque no sea exactamente el mismo).

En Linux puedes usar lsof para ver qué archivos abiertos (file descriptors) tiene tu aplicación, esto incluye sockets, las bibliotecas de la JVM etc así que es un poco difícil filtrarlo. Fugas de recursos siempre son un tanto difíciles de depurar, lo mejor es que hagas una revisión minuciosa de tu código. Un error típico es no cerrar recursos en finally, lo cual honestamente ya es imperdonable a partir de Java 7 porque es tan fácil con el try-with-resources.

Esto era típico en Java 6 y anteriores:

java.sql.Connection conn = null;
try {
  conn = //obtener la conexión
  conn.prepareStatement();
  //usar el statement
  conn.close();
} catch (SQLException ex) {
  System.out.println("chin");
}
//la conexión se queda abierta

La solución era poner el conn.close() en el bloque finally. Pero ahora simplemente:

try (Connection conn = bla) {
  //usar la conexión
} catch (SQLException ex) {
  println
}

Ya no es necesario cerrarla porque el try la cerrará automáticamente, pase lo que pase. Es más, en estos casos hasta el catch es opcional.

Imagen de avefenix_x

try-with-resources.. para usar esto asegurate de....

Asegurate de que la clase que usaras implemente AutoCloseable para que despues de su uso java de encargue de cerrar el recurso de forma adecuada, Tambien puedes hacer tu propia clase que implemente AutoCloseable, para este tipo de situaciones lo unico que se te obliga a programar es un metodo de close().

Busca en la documentacion de java para ver todos los recursos que tienes disponibles con esta forma de trabajar.

Saludos cordiales.

Imagen de paranoid_android

OK es valido revisar el software.

Ok es correcto No es aventar hardware así nomás.

No sé si el software está productivo o está en desarrollo. Asumí que ya estaba productivo.

Todo depende...
Si el caso es un software ya productivo te recomiendo primero descartar un truene por recursos o un truene por programación.
Para el truene por programación lo más sencillo es tratar de reproducir el error, si es un truene por recursos ver la demanda de recursos en horario o día, para identificar algún patrón.

Si no puedes reproducir el error muy probablemente tengas un error de recursos, también te conviene ver si el sistema puede tener algún tipo de afectación externa como por ejemplo acceso más lento cuando hace una consulta de otra aplicación o base de datos.

Hay que revisar el software sobre todo las últimas modificaciones.

Otra manera de encolar hilos es abuzar syncronized, abrir recursos costosos en cada petición, bloquear tablas, no usar índices. O acabarte un espacio asignado de escritura.

Imagen de avefenix_x

Aprovechando el tema de Memoria... :)

No tengo problemas de memoria pero hay un comportamieto de gasto de memoria estraño o normal :) segun sea el caso.
La app con spring y en tomcat arranca y con el visualVM monitoreo la memoria que inicialmente esta en 150M al arrancar tomcat, hago uso de un recurso y la memoria se lanza a 300M, termina el proceso en forma de zig zag entre 300 y 150M, pero entonces este mismo comportamiento(sin usar la app) se repite muchas veces disminuyendo picos de 300 , 295 , ect hasta que se estabiliza en 200 o 150M.. (Esto es un caso real con un solo usuario)

Quien dijo Yo.. para aclarar este comportamiento y ayudar con el tema.
Saludos cordiales.

Imagen de paranoid_android

Puedes probar la versión anterior

El zig zag en la memoria parece normal.

¿La versión anterior o la última versión estable tiene el mismo comportamiento?

En algunos web applications no sé si se pueda en tomcat se configura el máximo número de conexiones permitidas.
El numero por default es chico de modo que cuando aumentan los usuarios las conexiones se saturan y comienza a encolar hilos.
Este comportamiento posiblemente lo puedes simular con http://jmeter.apache.org/

Si esto no resulta posiblemente te sirva recopilar información exacta del momento de la degradación del servicio, identifica que operaciones se estan tardando más en el log.
Si es necesario agrega traza al código para que veas por donde va pasando al momento que ya no se puede acceder.

Imagen de echan

Mas parece un tema de

Mas parece un tema de retencion de memoria que de hilos( como comentan 300 no son muchos). Los errores en los logs deben servirte para diagnosticar el origen. De cualquier forma para ver si en alguna parte de la aplicacion estas reteniendo recursos puedes usar algun profiler, el de netbeans funciona basante bien.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">