2009-08-17 22 views
21

¿Cómo se determina el mejor número de maxSpare, minSpire y maxThreads, acceptCount, etc. en Tomcat? ¿Las mejores prácticas existentes?¿Cómo determinar el mejor número de subprocesos en Tomcat?

Entiendo que esto debe basarse en el hardware (por ejemplo, por núcleo) y solo puede ser una base para futuras pruebas de rendimiento y optimización en hardware específico.

Respuesta

46

el problema de "cuántos hilos" es un problema bastante grande y complicado, y no se puede responder con una simple regla general.

Teniendo en cuenta la cantidad de núcleos que tiene es útil para aplicaciones de múltiples hilos que tienden a consumir una gran cantidad de CPU, como el crujido de números y similares. Este es raramente el caso de una aplicación web, que generalmente no está acaparada por la CPU sino por otros factores.

Una de las limitaciones comunes es el desfase entre usted y otros sistemas externos, especialmente su base de datos. Cada vez que llega una solicitud, probablemente consultará la base de datos varias veces, lo que significa transmitir algunos bytes a través de una conexión JDBC, luego esperar que esos bytes lleguen a la base de datos (incluso si está en el host local todavía hay un pequeño retraso) , luego, esperando que el DB considere nuestra solicitud, luego espere a que la base de datos la procese (la base de datos en sí esperará que el disco busque una determinada región), etc.

Durante todo este tiempo, el el hilo está inactivo, por lo que otro hilo podría usar fácilmente esos recursos de CPU para hacer algo útil. Es bastante común ver entre el 40% y el 80% del tiempo dedicado a esperar la respuesta de la base de datos.

Lo mismo ocurre también en el otro lado de la conexión. Mientras un hilo suyo está escribiendo su salida en el navegador, la velocidad de la conexión CLIENTE puede mantener su hilo inactivo esperando que el navegador admita que se ha recibido un determinado paquete. (Esto fue un problema hace algunos años, los núcleos recientes y las JVM usan búferes más grandes para evitar que tus hilos se detengan de esa manera; sin embargo, un proxy inverso frente a tu servidor de aplicaciones web, incluso simplemente un httpd, puede ser realmente útil para evitar con mala conexión a Internet para actuar como ataques DDOS :))

Teniendo en cuenta estos factores, el número de subprocesos debe ser generalmente mucho más que los núcleos que tiene. Incluso en un simple servidor de doble o cuádruple núcleo, debe configurar al menos algunas docenas de hilos.

Entonces, ¿qué es lo que limita el número de subprocesos que puede configurar?

En primer lugar, cada hilo (utilizado para) consume muchos recursos. Cada hilo tiene una pila, que consume RAM. Además, cada subproceso realmente asignará cosas en el montón para hacer su trabajo, consumiendo nuevamente RAM, y el acto de cambiar entre subprocesos (cambio de contexto) es bastante pesado para el núcleo de JVM/OS.

Esto hace que sea difícil ejecutar un servidor con miles de subprocesos "sin problemas".

Ante este panorama, hay una serie de técnicas (en su mayoría: intentar, fallar, melodía, vuelve a intentarlo) para determinar con más o menos cuántos hilos que la aplicación va a necesitar:

1) tratar de entender donde su hilos pasan tiempo. Hay una serie de buenas herramientas, pero incluso jvisualvm profiler puede ser una gran herramienta, o un aspecto de rastreo que produce estadísticas de tiempo resumen. Cuanto más tiempo pasan esperando algo externo, más puedes generar más hilos para usar la CPU durante los tiempos muertos.

2) Determine su uso de RAM.Dado que la JVM utilizará una cierta cantidad de memoria (sobre todo el espacio permgen, generalmente hasta cien megabytes, de nuevo jvisualvm dirá) independientemente de la cantidad de hilos que utilice, intente ejecutar con un hilo y luego con diez y luego con cien, mientras enfatiza la aplicación con jmeter o lo que sea, y vea cómo crecerá el uso del montón. Eso puede suponer un límite difícil.

3) Trate de determinar un objetivo. Cada solicitud de usuario necesita un hilo para ser manejado. Si su tiempo de respuesta promedio es de 200 ms por "obtener" (sería mejor no considerar la carga de imágenes, CSS y otros recursos estáticos), cada subproceso puede servir 4/5 páginas por segundo. Si se espera que cada usuario "haga clic" cada 3/4 segundos (depende, ¿es un juego de navegador o un sitio con muchos textos largos?), Entonces un hilo "servirá a 20 usuarios concurrentes", sea lo que sea. Si en la hora punta tienes 500 usuarios únicos que visitan tu sitio en 1 minuto, entonces necesitas suficientes hilos para manejar eso.

4) Prueba de colisión el límite superior. Use jmeter, configure un servidor con muchos subprocesos en una máquina virtual de repuesto y vea cómo el tiempo de respuesta empeorará cuando sobrepase cierto límite. Más que hardware, la implementación de subprocesos del sistema operativo subyacente es importante aquí, pero no importa qué alcance un punto en el que la CPU pase más tiempo tratando de averiguar qué hilo ejecutar que realmente ejecutarlo, y ese número no es tan increíble. alto.

5) Considere cómo los hilos afectarán a otros componentes. Cada hilo probablemente usará una (o quizás más de una) conexión a la base de datos, ¿la base de datos puede manejar 50/100/500 conexiones concurrentes? Incluso si está utilizando un clúster fragmentado de servidores nosql, ¿la granja de servidores ofrece suficiente ancho de banda entre esas máquinas? ¿Qué más se ejecutará en la misma máquina con el servidor de la aplicación web? Anache httpd? ¿calamar? la base de datos en sí? un proxy de almacenamiento en caché local a la base de datos como mongos o memcached?

He visto sistemas en producción con solo 4 hilos + 4 hilos de repuesto, porque el trabajo realizado por ese servidor era simplemente cambiar el tamaño de las imágenes, por lo que era casi 100% intensivo de la CPU y otros configuraban más o menos mismo hardware con un par de cientos de subprocesos, porque la aplicación estaba haciendo muchas llamadas SOAP a sistemas externos y pasaba la mayor parte del tiempo esperando respuestas.

Oce usted ha determinado el aprox. hilos mínimos y máximos óptimos para su aplicación webapp, entonces generalmente lo configuro de esta manera:

1) En función de las restricciones en la RAM, otros recursos externos y experimentos en el cambio de contexto, hay un máximo absoluto que no se debe alcanzar. Entonces, use maxThreads para limitarlo a aproximadamente la mitad o 3/4 de ese número.

2) Si la aplicación es razonablemente rápida (por ejemplo, expone los servicios web REST que suelen enviar una respuesta unos pocos milisegundos), puede configurar un acceptCount grande, hasta el mismo número de maxThreads. Si tiene un equilibrador de carga en frente de su servidor de aplicaciones web, establezca un pequeño acceptCount, es mejor que el equilibrador de carga vea las solicitudes no aceptadas y cambie a otro servidor que ponga a los usuarios en espera en uno ya ocupado.

3) Ya que el inicio de un hilo es (todavía) considerado una operación pesada, use minSpareThreads para tener algunos hilos listos cuando llegan las horas punta. De nuevo, esto depende del tipo de carga que está esperando. Incluso es razonable tener las configuraciones minSpareThreads, maxSpareThreads y maxThreads para que siempre haya un número exacto de subprocesos listos, nunca recuperados y las actuaciones sean predecibles. Si está ejecutando tomcat en una máquina dedicada, puede generar minSpareThreads y maxSpareThreads sin ningún peligro de acaparar otros procesos; de lo contrario, sintonícelos porque los hilos son recursos compartidos con el resto de los procesos que se ejecutan en la mayoría de los sistemas operativos.

Cuestiones relacionadas