Tomcat - Introducción

Tomcat es un contenedor de Servlets con un entorno JSP. Un contenedor de Servlets es un shell de ejecución que maneja e invoca servlets por cuenta del usuario.

Podemos dividir los contenedores de Servlets en:

  1. Contenedores de Servlets Stand-alone (Independientes)
    Estos son una parte integral del servidor web. Este es el caso cuando usando un servidor web basado en Java, por ejemplo, el contenedor de servlets es parte de JavaWebServer (actualmente sustituido por iPlanet). Este el modo por defecto usado por Tomcat.
    Sin embargo, la mayoría de los servidores, no están basados en Java, los que nos lleva los dos siguientes tipos de contenedores:
  2. Contenedores de Servlets dentro-de-Proceso
    El contenedor Servlet es una combinación de un plugin para el servidor web y una implementación de contenedor Java. El plugind del servidor web abre una JVM (Máquina Virtual Java) dentro del espacio de direcciones del servidor web y permite que el contenedor Java se ejecute en él. Si una cierta petición debería ejecutar un servlet, el plugin toma el control sobre la petición y lo pasa al contenedor Java (usando JNI). Un contenedor de este tipo es adecuado para servidores multi-thread de un sólo proceso y proporciona un buen rendimiento pero está limitado en escalabilidad
  3. Contenedores de Servlets fuera-de-proceso
    El contenedor Servlet es una combinación de un plugin para el servidor web y una implementación de contenedor Java que se ejecuta en una JVM fuera del servidor web. El plugin del servidor web y el JVM del contenedor Java se comunican usando algún mecanismo IPC (normalmente sockets TCP/IP). Si una cierta petición debería ejecutar un servlet, el plugin toma el control sobre la petición y lo pasa al contenedor Java (usando IPCs). El tiempo de respuesta en este tipo de contenedores no es tan bueno como el anterior, pero obtiene mejores rendimientos en otras cosas (escalabilidad, estabilidad, etc.).

Tomcat puede utilizarse como un contenedor solitario (principalmente para desarrollo y depuración) o como plugin para un servidor web existente (actualmente se soporan los servidores Apache, IIS y Netscape). Esto significa que siempre que despleguemos Tomcat tendremos que decidir cómo usarlo, y, si seleccionamos las opciones 2 o 3, también necesitaremos instalar un adaptador de servidor web

. ¿Cuál es la Diferencia entre Tomcat y Jserv?
¿No es Tomcat == Jserv?

Es una confusión común, Jserv es un contenedor compatible con el API Servlet 2.0 que fue creado para usarse con Apache. Tomcat es una re-escritura completa y es un contenedor compatible con los APIs Servlet 2.2 y JSP 1.1.

Tomcat utiliza algún código escrito para Jserv, especialmente el adaptador de servidor para Apache, pero aquí se terminan todas las similitudes.

. ¿Cómo Instalar la Versión Binaria de Tomcat?

Muy sencillo. Deberíamos:

  • Descargar el fichero zip/tar.gz/ desde http://jakarta.apache.org/downloads/binindex.html.
  • Desempaquetamos el fichero en algún directorio (digamos foo). Esto debería crear un subdirectorio llamado jakarta-tomcat-3.2.1. Si no es el lugar que queremos, movemos este directorio a la localización deseada.
  • Cambiamos al directorio jakarta-tomcat-3.2.1 y configuramos una nueva variable de entorno (TOMCAT_HOME) que apunte a la raíz de nuestro directorio Tomcat.
    1. En Win32 deberíamos teclear:
      set TOMCAT_HOME=foo\jakarta-tomcat-3.2.1
      
    2. Sobre UNIX deberíamos teclear:
      para bash/sh:
      TOMCAT_HOME=foo/jakarta-tomcat-3.2.1 ; 
      export TOMCAT_HOME
      
      para tcsh
      setenv TOMCAT_HOME foo/jakarta-tomcat-3.2.1
      
  • Configuramos la variable de entorno JAVA_HOME para que apunte al directorio raíz de nuestra instalación del JDK, luego añadimos el intérprete Java a nuestra variable de entorno PATH.

¡Esto es todo! Ahora podemos ejecutar Tomcat y se ejecutará como un contenedor de servlets independiente (del tipo 1).

. Arrancar y Parar Tomcat

>

Arrancamos y paramos Tomcat usando los scripts que hay en el directorio bin:

Para arrancar Tomcat ejecutamos:

  • Sobre UNIX:
    bin/startup.sh
    
  • Sobre Win32:
    bin\startup
    

Para parar Tomcat ejecutamos:

  • Sobre UNIX:
    bin/shutdown.sh
    
  • Sobre Win32:
    bin\shutdown
    

. La Estructura de Directorios de Tomcat

Asumiendo que hemos descomprimido la distribución binaria de Tomcat deberíamos tener la siguiente estructura de directorios:

Nombre de Directorio Descripción
bin Contiene los scripts de arrancar/parar
conf Contiene varios ficheros de configuración incluyendo server.xml (el fichero de configuración principal de Tomcat) y web.xml que configura los valores por defecto para las distintas aplicaciones desplegadas en Tomcat.
doc Contiene varia documentación sobre Tomcat (Este manual, en Inglés).
lib Contiene varios ficheros jar que son utilizados por Tomcat. Sobre UNIX, cualquier fichero de este directorio se añade al classpath de Tomcat.
logs Aquí es donde Tomcat sitúa los ficheros de diario.
src Los ficheros fuentes del API Servlet. ¡No te excites, todavía! Estoa son sólo los interfaces vacíos y las clases abstractas que debería implementar cualquier contenedor de servlets.
webapps Contiene aplicaciones Web de Ejemplo.

Adicionalmente podemos, o Tomcat creará, los siguientes directorios:

Nombre de Directorio Descripción
work Generado automáticamente por Tomcat, este es el sitio donde Tomcat sitúa los ficheros intermedios (como las páginas JSP compiladas) durante su trabajo. Si borramos este directorio mientras se está ejecutando Tomcat no podremos ejecutar páginas JSP.
classes Podemos crear este directorio para añadir clases adicionales al classpath. Cualquier clase que añadamos a este directorio encontrará un lugar en el classpath de Tomcat.

. Los Scripts de Tomcat

Tomcat es un programa Java, y por lo tanto es posible ejcutarlo desde la línea de comandos, después de configuar varias variables de entorno. Sin embargo, configurar cada variable de entorno y seguir los parámetros de la línea de comandos usados por Tomcat es tedioso y propenso a errores. En su lugar, el equipo de desarrollo de Tomcat proporciona unos pocos scripts para arrancar y parar Tomcat fácilmente.

Nota: Los scripts son sólo una forma conveniente de arrancar/parar... Podemos modificarlos para personalizar el CLASSPATH, las variables de entorno como PATH y LD_LIBRARY_PATH, etc., mientras que se genera la línea de comandos correcta para Tomcat.

¿Qué son esos scripts? La siguiente tabla presenta los scripts más importantes para el usuario común:

Nombre del Script Descripción
tomcat El script principal. Configura el entorno apropiado, incluyendo CLASSPATH, TOMCAT_HOME y JAVA_HOME, y arranca Tomcat con los parámetros de la línea de comando apropiados.
startup Arrancar tomcat en segundo plano. Acceso directo para tomcat start
shutdown Para tomcat (lo apaga). Acceso directo para tomcat stop;

El script más importante para los usuarios es tomcat (tomcat.sh/tomcat.bat). Los otros scripts relacionados con tomcat sirven como un punto de entrada simplificado a una sola tarea (configuran diferentes parámetros de la línea de comandos, etc.).

Una mirada más cercana a tomcat.sh/tomcat.bat nos muestra que realiza las siguientes acciones:

Sistema Operativo Acciones
Unix
  • Averigua donde está TOMCAT_HOME si no se especifica.
  • Averigua donde está JAVA_HOME si no se especifica.
  • Configura un CLASSPATH que contiene -
    1. El directorio ${TOMCAT_HOME}/classes (si exsiste).
    2. Todo el contenido de ${TOMCAT_HOME}/lib.
    3. ${JAVA_HOME}/lib/tools.jar (este fichero jar contine la herramienta javac, que necesitamos para compilar los ficheros JSP).
  • Ejecuta java con los parámetros de la línea de comandos que ha configurado un entorno de sistema Java, llamado tomcat.home, con org.apache.tomcat.startup.Tomcat como la clase de arranque. También procesa los parámetros de la línea de comandos para org.apache.tomcat.startup.Tomcat, como:
    1. La operación a ejecutar start/stop/run/etc.
    2. Un path al fichero server.xml usado por este proceso Tomcat.

    Por ejemplo, si server.xml está localizado en /etc/server_1.xml y el usuario quiere arrancar Tomcat en segundo plano, debería introducir la siguiente línea de comandos:

    bin/tomcat.sh start -f /etc/server_1.xml
    
Win32
  • Graba las configuraciones actuales para TOMCAT_HOME y CLASSPATH.
  • Prueba JAVA_HOME para asegurarse de que está configurado.
  • Prueba si TOMCAT_HOME está configurado y los valores por defecto a "." no lo están. Entonces se usa TOMCAT_HOME para probar la existencia de servlet.jar para asegurarse de que TOMCAT_HOME es válido.
  • Configura la varibale CLASSPATH que contiene -
    1. %TOMCAT_HOME%\classes (incluso si no existe),
    2. Los ficheros Jar de %TOMCAT_HOME%\lib. Si es posible, todos los ficheros jar en %TOMCAT_HOME%\lib sin incluidos dinámicamente. Si no es posible, se incluyen estáticamente los siguientes ficheros jar: ant.jar, jasper.jar, jaxp.jar, parser.jar, servlet.jar, y webserver.jar
    3. %JAVA_HOME%\lib\tools.jar, si existe (este fichero jar contiene la herramietna javac necesaria para compilar los ficheros JSP).
  • Ejecuta %JAVA_HOME%\bin\java, con los parámetros de la línea de comandos que configuran el entorno de sistema Java, llamado tomcat.home, con org.apache.tomcat.startup.Tomcat como la clase de arranque. También le pasa los parámetros de la líena de comandos a org.apache.tomcat.startup.Tomcat, como:
    1. La operación a realizar: start/stop/run/etc.
    2. Un path al fichero server.xml usado por este proceso Tomcat.

    Por ejemplo, si server.xml está localizado en conf\server_1.xml y el usuario quiere arrancar Tomcat en una nueva ventana, debería proporcionar la siguiente línea de comando:

    bin\tomcat.bat start -f conf\server_1.xml
    
  • Restaura las configuraciones de TOMCAT_HOME y CLASSPATH grabadas préviamente.

Como podemos ver, la versión Win32 de tomcat.bat no es tán robusta como la de UNIX. Especialmente, no se averigua los valores de JAVA_HOME y sólo intenta "." como averiguación de TOMCAT_HOME. Puede construir el CLASSPATH dinámicamente, pero no en todos los casos. No puede construir el CLASSPATH dinámincamente si TOMCAT_HOME contiene espacios, o sobre Win9x, si TOMCAT_HOME contiene nombres de directorios que no son 8.3 caracteres.

. Ficheros de Configuración de Tomcat

La configuración de Tomcat se basa en dos ficheros:

  1. server.xml - El fichero de configuración golbal de Tomcat.
  2. web.xml - Configura los distintos contextos en Tomcat.

Esta sección trata la forma de utilizar estos ficheros. No vamos a cubrir la interioridades de web.xml, esto se cubre en profundidad en la especificación del API Servlet. En su lugar cubriremos el contenido de server.xml y discutiremos el uso de web.xml en el contexto de Tomcat.

. server.xml

server.xml es el fichero de configuración principal de Tomcat. Sirve para dos objetivos:

  1. Proporcionar configuración inicial para los componentes de Tomcat.
  2. Especifica la estructura de Tomcat, lo que significa, permitir que Tomcat arranque y se construya a sí mismo ejemplarizando los componentes especificados en server.xml.

Los elementos más importantes de server.xml se describen en la siguiente tabla:

Elemento Descripción
Server El elemento superior del fichero server.xml. Server define un servidor Tomcat. Generalmente no deberíamos tocarlo demasiado. Un elemento Server puede contener elementos Logger y ContextManager.
Logger Este elemento define un objeto logger. Cada objeto de este tipo tiene un nombre que lo identifica, así como un path para el fichero log que contiene la salida y un verbosityLevel (que especifica el nivel de log). Actualmente hay loggeres para los servlets (donde va el ServletContext.log()), los ficheros JSP y el sistema de ejecución tomcat.
ContextManager Un ContextManager especifica la configuración y la estructura para un conjunto de ContextInterceptors, RequestInterceptors, Contexts y sus Connectors. El ContextManager tiene unos pocos atributos que le proporcionamos con:
  1. Nivel de depuración usado para marcar los mensajes de depuración
  2. La localización base para webapps/, conf/, logs/ y todos los contextos definidos. Se usa para arrancar Tomcat desde un directorio distinto a TOMCAT_HOME.
  3. El nombre del directorio de trabajo.
  4. Se incluye una bandera para controlar el seguimiento de pila y otra información de depurado en las respuestas por defecto.
ContextInterceptor & RequestInterceptor Estos interceptores escuchan ciertos eventos que sucenden en el ContextManager. Por ejemplo, el ContextInterceptor escucha los eventos de arrancada y parada de Tomcat, y RequestInterceptor mira las distintas fases por las que las peticiones de usuario necesitan pasar durante su servicio. El administrador de Tomcat no necesita conocer mucho sobre los interceptores; por otro lado, un desarrollador debería conocer que éste es un tipo global de operaciones que pueden implementarse en Tomcat (por ejemplo, loggin de seguridad por petición).
Connector El Connector representa una conexión al usuario, a través de un servidor Web o directamente al navegador del usuario (en una configuración independiente). El objeto connector es el responsable del control de los threads en Tomcat y de leer/escribir las peticiones/respuestas desde los sockets conectados a los distintos clientes. La configuración de los conectores incluye información como:
  1. La clase handler.
  2. El puerto TCP/IP donde escucha el controlador.
  3. el backlog TCP/IP para el server socket del controlador.
Describiremos cómo se usa esta configuración de conector más adelante.
Context Cada Context representa un path en el árbol de tomcat donde situanos nuestra aplicación web. Un Context Tomcat tiene la siguiente configuración:
  1. El path donde se localiza el contexto. Este puede ser un path completo o relativo al home del ContextManager.
  2. Nivel de depuración usado para los mensaje de depuración.
  3. Una bandera reloadable. Cuando se desarrolla un servlet es muy conveniente tener que recargar el cambio en Tomcat, esto nos permite corregir errores y hacer que Tomcat pruebe el nuevo código sin tener que parar y arrancar. Para volver a recargar el servlet seleccionamos la bandera reloadable a true. Sin embargo, detectar los cambios consume tiempo; además, como el nuevo servlet se está cargando en un nuevo objeto class-loader hay algunos casos en los que esto lanza errores de forzado (cast). Para evitar estos problemas, podemos seleccionar la bandera reloadable a false, esto desactivará esta característica.

Se puede encontrar información adicional dentro del fichero server.xml.

. Arrancar Tomcat dese Otros Directorio

Por defecto tomcat usará TOMCAT_HOME/conf/server.xml para su configuración. La configuración por defecto usará TOMCAT_HOME como la base para sus contextos.

Podemos cambiar esto usando la opción -f /path/to/server.xml, con un fichero de configuración diferente y configurando la propiedad home del controlador de contexto. Necesitamos configurar los ficheros requeridos dentro del directorio home:

  • Un directorio webapps/ (si hemos creado uno) - todos los ficheros war se expanderán y todos sus subdirectorios se añadirán como contextos.
  • Directorio conf/ - podemos almacenar tomcat-users.xml y otros ficheros de configuración.
  • logs/ - todos los logs irán a este directorio en lugar de al principal TOMCAT_HOME/logs/.
  • work/ - directorio de trabajo para los contextos.

Si la propiedad ContextManager.home de server.xml es relativa, será relativa al directorio de trabajo actual.

. web.xml

Podemos encontar una detallada descripción de web.xml y la estructura de la aplicación web (incluyendo la estructura de directorios y su configuración) en los capítulo 9, 10 y 14 de la Servlet API Spec en la site de Sun Microsystems.

Hay una pequeña característica de Tomcat que está relacionada con web.xml. Tomcat permite al usuario definir los valores por defecto de web.xml para todos los contextos poniendo un fichero web.xml por defecto en el directorio conf. Cuando construimos un nuevo contexto, Tomcat usa el fichero web.xml por defecto como la configuración base y el fichero web.xml específico de la aplicación (el localizado en el WEB-INF/web.xml de la aplicación), sólo sobreescribe estos valores por defecto.

. Configurar Tomcat para Cooperar con Apache Web Server

Hasta ahora no hemos explicado Tomcat como un plugin, en su lugar lo hemos considerado como un contenedor independiente y hemos explicado como usarlo. Sin embargo, hay algunos problemas:

  1. Tomcat no es tan rápido como Apache cuando sirve páginas estáticas.
  2. Tomcat no es tan configurable como Apache.
  3. Tomcat no es tan robusto como Apache.
  4. Hay mucho sites que llavan mucho tiempo de investigación sobre ciertos servidores web, por ejemplo, sites que usan scripts CGI o módulos perl o php... No podemos asumir que todos ellos quieran abandonar dichas tecnologías.

Por todas estas razones es recomendable que las sites del mundo real usen un servidor web, como Apache, para servir el contenido estático de la site, y usen Tomcat como un plugin para Servlets/JSP.

No vamos a cubrir las diferentes configuraciones en profundidad, en su lugar:

  1. Cubriremos el comportamiento fundamental de un servidor web.
  2. Explicaremos la configuración que necesitamos.
  3. Demonstraremos esto sobre Apache.

. Operación del Servidor Web

En resumidas cuentas un servidor web está esperando peticiones de un cliente HTTP. Cuando estas peticiones llegan el servidor hace lo que sea necesario para servir las peticiones proporcionando el contenido necesario. Añadirle un contenedor de servlets podría cambiar de alguna forma este comportamiento. Ahora el servidor Web también necesita realizar lo siguiente:

  • Cargar la librería del adaptador del contenedor de servlets e inicializarlo (antes de servir peticiones).
  • Cuando llega una petición, necesita chequear para ver si una cierta petición pertenece a un servlet, si es así necesita permitir que el adaptador tome el control y lo maneje.

Por otro lado el adaptador necesita saber qué peticiones va a servir, usualmente basándose en algún patrón de la URL requerida, y dónde dirigir estas peticiones.

Las cosas son incluso más complejas cuando el usuario quiere seleccionar una configuración que use hosts virtuales, o cuando quieren que múltiples desarrolladores trabajen en el mismo servidor web pero en distintos contenedores de Servlets. Cubriremos estos dos casos en las secciones avanzadas.

. ¿Cuál es la Configuración Necesaria

La configuración más óbvia en la que uno puede pensar es en la identidad de las URLs servlet que están bajo la responsabilidad del contenedor de servlets. Esto está claro, alguién debe conocer qué peticiones transmitir al cotenedor de servlets...
Todavía hay algunos ítems de configuración adicionales que deberíamos proporcionar a la combinación web-server/servlet-container:

  • Necesitamos proporcionar la configuración sobre los procesos Tomcat disponibles y sobre los puertos/host TCP/IP sobre los que éstos están escuchando.
  • Necesitamos decirle al servidor web la localización de la librería adaptador (para que pueda cargarla en la arrancada).
  • Necesitamos seleccionar la información interna del adaptador sobre cuando log guardar, etc.

Toda esta información debe aparecer en el fichero de configuración del servidor web, o en un fichero de configuración privado usado por el adaptador. La siguiente sección explicará cómo se puede implementar esta configuración en Apache.

. Haciéndolo en Apache

Esta sección nos enseña como configurar Apache para que trabaje con Tomcat; intenta proporcionar explicaciones sobre las directivas de configuración que deberíamos usar. Podemos encontrar información adicional en la página http://java.apache.org/jserv/install/index.html.

Cuando Tomcat arranque generá automáticamente un fichero de configuración para apache en TOMCAT_HOME/conf/tomcat-apache.conf. La mayoría de las veces no necesitaremos hacer nada más que incluir es fichero (añadir Include TOMCAT_HOME/conf/tomcat-apache.conf) en nuestro fichero httpd.conf. Si tenemos necesidades especiales, por ejemplo un puerto AJP distinto de 8007, podemos usar este fichero como base para nuestra configuración personalizada y grabar los resultados en otro fichero. Si manejamos nosotros mismos la configuración de Apache necesitaremos actualizarlo siempre que añadamos un nuevo contexto.

Tomcat: debemos re-arrancar tomcat y apache después de añadir un nuevo contexto; Apache no soporta cambios en su configuración sin re-arrancar. Cuando tomcat arranca, también se genera el fichero TOMCAT_HOME/conf/tomcat-apache.conf cuando arrancar tomcat, por eso necesitamos arrancar Tomcat antes que Apache. Tomcat sobreescribirá TOMCAT_HOME/conf/tomcat-apache.conf cada arrancada para que se mantenga la configuración peronalizada.

La configuración Apache-Tomcat usa las directivas de configuración principales de Apache así como directivas únicas de Jserv por eso podría ser confuso al principio, sin embargo hay dos cosas que lo simplifican:

  • En general podemos distinguir dos familias de directivas porque las directivas únicas de jserv empiezan con un prefijo ApJServ.
  • Toda la configuración relacionada con Tomcat está concentrada en un sólo fichero de configuración llamado tomcat.conf, el automáticamente generado tomcat-apache.conf, por eso podemos mirar en un sólo fichero.

Veamos ahora un simple fichero tomcat.conf:

    
###########################################################
#      A minimalistic Apache-Tomcat Configuration File    #
###########################################################

# Note: this file should be appended or included into your httpd.conf

# (1) Loading the jserv module that serves as Tomcat's apache adapter.
LoadModule jserv_module libexec/mod_jserv.so

# (1a) Module dependent configuration.
<IfModule mod_jserv.c>

# (2) Meaning, Apache will not try to start Tomcat.
ApJServManual on
# (2a) Meaning, secure communication is off
ApJServSecretKey DISABLED
# (2b) Meaning, when virtual hosts are used, copy the mount
# points from the base server
ApJServMountCopy on
# (2c) Log level for the jserv module.
ApJServLogLevel notice

# (3) Meaning, the default communication protocol is ajpv12
ApJServDefaultProtocol ajpv12
# (3a) Default location for the Tomcat connectors.
# Located on the same host and on port 8007
ApJServDefaultHost localhost
ApJServDefaultPort 8007

# (4)
ApJServMount /examples /root
# Full URL mount
# ApJServMount /examples ajpv12://hostname:port/root
</IfModule>

Como podemos ver el proceso de configuración está dividio en 4 pasos que explicaremos ahora:

  1. En este paso instruimos a Apache para que carque el objeto compartido jserv (o la librería dll en NT). Esta es una directiva familiar de Apache. Si la carga fue bien y el módulo vino de un fichero llamado mod_jserv.c (1a) podemos arrancar con el resto de la configuración Jserv-Tomcat.
  2. Este paso configura varios parámetros internos de Jserv, estos parámetros son:
    • Instruye a jserv para que no arranque el proceso Tomcat. Esto no está implementado todavía.
    • Desactiva la clave secreta challenge/response entre Apache y Tomcat. De nuevo, esto tampo está implementado aún.
    • Instruye a jserv para que copie el punto de montaje del servidor base (ver siguiente seccion) en caso de hosting virtual
    • Instruye a jserv para usar el nivel de log de noticia. Otros niveles de log incluidos son: emerg, alert, crit, error, warn, info y debug.
  3. Este paso configura los parámetros de comunicación por defecto. Básicamente dice que el protocolo por defecto utilizado para la comunicación es ajpv12 que el proceso Tomcat se ejecuta sobre la misma máquina y que escucha en el puerto 8807. Si ejecutamos Tomcat en una máquina distinta a las usada por Apache deberíamos actualizar ApJServDefaultHost o usar una URL completa cuando montemos los contextos. Tambien, si configuramos los conectores Tomcat para usar un puerto distinto al 8007, deberíamos actualizar ApJServDefaultPort o usar una URL completa cuando montemos los contextos.
  4. Este paso monta un contexto para Tomcat. Básicamente dice que todos los paths del servidor web que empiecen con /example irán a Tomcat. Este ejemplo ApJServMount es uno muy simple, de hecho, ApJServMount también puede proporcionar información sobre el protocolo de comunicación usado y la localización donde está escuchando el proceso Tomcat, por ejemplo:
    ApJServMount /examples ajpv12://hostname:port/root
    
    monta el contexto /examples en un proceso tomcat que se está ejecutando en el host hostname y que escucha en el puerto número port.

Ahora que hemos entendido las diferentes instrucciones de configuración en el fichero de ejemplo, ¿cómo podríamos añadirla a la configuración de Apache? Un método sencillo es escribir su contenido en httpd.conf (el fichero de configuración de Apache), sin embargo, esto puede ser muy desordenado. En su lugar deberíamos usar la directiva include de apache. Al final de fichero de configuración de Apache (httpd.conf) añadimos la siguiente directiva:

include <full path to the Tomcat configuration file>

Por ejemplo:

include /tome/tomcat/conf/tomcat.conf

Esto añadirá nuestra configuración de Tomcat a apache, después de haber copiado el módulo jserv al directorio libexec de Apache (o modules en caso de Win32) y re-arrancar (parar+arrancar) Apache, deberíamos poder conectar con Tomcat.

. Obtener el Módulo Jserv (mod_jserv)

Como vimos anteriormente, necesitamos un adaptador de servidor Web para situarlo en Apache y redirigir las peticiones a Tomcat. Para Apache, este adaptador es una versión ligeramente modificada de mod_jserv.

Podríamos intentar buscarlo en http://jakarta.apache.org/downloads/binindex.html para ver si hay una versión pre-construida de mod_jserv que corresponda con nuestro sistema operativo (Normalmente hay uno para NT), sin embargo, siendo una librería nativa, no deberíamos esperar que esté ya (demasiados sistemas operativos, pocos desarrolladores, la vida es muy corta...) Además, pequeñas variaciones en la forma de construir la variante UNIX de Apache podrían resultar en errores de enlaces dinámicos. Realmente deberíamos intentar construir mod_jserv para nuestro sistema (no te asustes, no es tan dificil!).

Construir mod_jserv sobre UNIX:

  1. Descargar la distribución fuente de Tomcat desde http://jakarta.apache.org/downloads/sourceindex.html.
  2. Descomprimirla en algún directorio.
  3. Construir el módulo:
    • Mover el directorio a jakarta-tomcat/src/native/apache/jserv/
    • Ejcutar el comando para construirlo:
      apxs -c -o mod_jserv.so *.c
      
      apxs es parte de la distribución de Apache y debería estar localizado en nuestro APACHE_HOME/bin.

Construir mod_jserv para Win32 no es tan sencillo (ya tenemos una dll descargable para Win32). Pero si todavía queremos construirlo deberíamos instalar visual C++ y realizar las siguientes tareas:

  1. Descargar la distribución fuente de Tomcat desde http://jakarta.apache.org/downloads/sourceindex.html.
  2. Descomprimirla en algún directorio.
  3. Construir el módulo:
    • Mover el directorio a jakarta-tomcat\src\native\apache\jserv
    • Añadir Visual C++ a nuestro entorno ejecutando el script VCVARS32.BAT.
    • Configurar una variable de entorno llamada APACHE_SRC que apunte al directorio source de Apache, es decir SET APACHE_SRC=C:\Program Files\Apache Group\Apache\src. Observa que el fichero make espera enlazar con CoreR\ApacheCore.lib bajo el directorio APACHE_SRC. Puedes ver la documentación de Apache para construir ApacheCore.
    • Ejecutamos el comando para construir:
      nmake -f Makefile.win32
      
      nmake es el programa make de Visual C++.

Esto es todo!, ya hemos construido mod_jserv...

. Hacer que Apache sirva los Ficheros Estáticos del Contexto

El fichero anterior de configuración de Apache-Tomcat era de alguna forma ineficiente, instruye a Apache a enviar cualquier petición que empiece con el prefijo /examples para que sea servida por Tomcat. ¿Realmente queremos hacer eso? Hay muchos ficheros estáticos que podrían ser parte de nuestro contexto servlet (por ejemplo imágenes y HTML estático), ¿Por qué debería Tomcat servir esos ficheros?

Realmente tenemos razones para hacer esto, por ejemplo:

  1. Podríamos querer configurar Tomcat basándonos en la seguridad para esos recursos.
  2. Podríamos querer seguir las peticiones de usuarios de recursos estáticos usando interceptores.

En general, sin embargo, este no es ese caso; hacer que Tomcat sirva el contenido estático es sólo malgastar CPU. Deberíamos hacer que Apache sirviera estos ficheros dinámicos y no Tomcat.

Hacer que Apache sirva los ficheros estáticos requiere los siguientes pasos:

  1. Instruir a Apache para que envíe todas la peticiones servlet a Tomcat
  2. Instruir a Apache para que envíe todas las peticiones JSP a Tomcat.

y dejar que Apache maneje el resto. Echemos un vistazo a un fichero de ejemplo tomcat.conf que hace exactamente esto:

    
######################################################################
#              Apache-Tomcat Smart Context Redirection               #
######################################################################
LoadModule jserv_module modules/ApacheModuleJServ.dll
<IfModule mod_jserv.c>
ApJServManual on
ApJServDefaultProtocol ajpv12
ApJServSecretKey DISABLED
ApJServMountCopy on
ApJServLogLevel notice

ApJServDefaultHost localhost
ApJServDefaultPort 8007

#
# Mounting a single smart context:
#
# (1) Make Apache know about the context location.
Alias /examples c:/jakarta-tomcat/webapps/examples
# (2) Optional, customize Apache context service.
<Directory "c:/jakarta-tomcat/webapps/examples">
    Options Indexes FollowSymLinks
# (2a) No directory indexing for the context root.
#    Options -Indexes
# (2b) Set index.jsp to be the directory index file.
#    DirectoryIndex index.jsp
</Directory>
# (3) Protect the WEB-INF directory from tampering.
<Location /examples/WEB-INF/>
    AllowOverride None
    deny from all
</Location>
# (4) Instructing Apache to send all the .jsp files under the context to the 
# jserv servlet handler. 
<LocationMatch /examples/*.jsp>
    SetHandler jserv-servlet
</LocationMatch>
# (5) Direct known servlet URLs to Tomcat.
ApJServMount /examples/servlet /examples

# (6) Optional, direct servlet only contexts to Tomcat.
ApJServMount /servlet /ROOT
</IfModule>

Como podemos ver, el inicio de este fichero de configuración es el mismo que vimos en el ejemplo anterior. Sin embargo, el último paso (montar el contexto), ha sido reemplazado por una larga serie de directivas de configuración de Apache y ApJServ que ahora explicaremos:

  1. Este paso informa a Apache de la localización del contexto y los asigna a un directorio virtual de Apache. De esta forma Apache puede servir ficheros de este directorio.
  2. Este paso opcional instruye a Apache sobre cómo servir el contexto; por ejemplo podemos decidir si Apache permitirá indexar (listar) el directorio o seleccionar un fichero de indice especial.
  3. Este paso instruye a Apache para proteger el directorio WEB-INF de los accesos del cliente. Por razones de seguridad es importante evitar que los visitante vean el contenido del directorio WEB-INF, por eemplo web.xml podría proporcionar información valiosa a los intrusos. Este paso bloquea el contenido de WEB-INF para los visitiantes.
  4. Este paso instruye a Apache para que sirva todas las localizaciones JSP dentro del contexto usando el manejador de servlets jserv. El manejador de servlet redirige estas peticiones basándose en el host y puerto por defecto.
  5. Este paso monta las URLs específicas de servelts en Tomcat. Deberíamos observar que deberíamos tener tantas directivas como el número de URLs de servlets especificados.
  6. Este último paso es un ejemplo de adición de un único contexto servlet a Tomcat.

Es facil ver que este fichero de configuración es mucho más complejo y propenso a errores que el primer ejemplo, sin embargo es el precio que debemos pagar (por ahora) para mejorar el rendimiento.

. Configurar Varias JVMs Tomcat

Algunas veces es útil tener diferentes contextos manejados por diferentes JVMs (Máquinas Virtuales Java), por ejemplo:

  • Cuando cada contexto sirve a una tarea específica y diferente y se ejecuta sobre una máquina distinta.
  • Cuando queremos tener varios desarrolladores trabajando en un proceso Tomcat privado pero usando el mismo servidor web

Implementar dichos esquemas donde diferentes contextos son servidos por diferentes JVMs es muy fácil y el siguiente fichero de configuración lo demuestra:

    
######################################################################
#             Apache-Tomcat with JVM per Context                     #
######################################################################
LoadModule jserv_module modules/ApacheModuleJServ.dll
<IfModule mod_jserv.c>
ApJServManual on
ApJServDefaultProtocol ajpv12
ApJServSecretKey DISABLED
ApJServMountCopy on
ApJServLogLevel notice

ApJServDefaultHost localhost
ApJServDefaultPort 8007

# Mounting the first context.
ApJServMount /joe ajpv12://joe.corp.com:8007/joe

# Mounting the second context.
ApJServMount /bill ajpv12://bill.corp.com:8007/bill
</IfModule>

Como podemoe ver en el ejemplo anterior, usar varias JVMs (incluso aquellas que se ejecutan en diferentes máquinas) puede conseguirse fácilmente usando una URL completa ajp montada. En esta URL completa realmente especificamos el host donde está localizado el proceso Tomcat y su puerto.

Si tuvieramos los dos procesos Tomcat ejecutándose en la misma máquina, Deberíamos configurar cada uno de ellos con un puerto de conector diferente. Por ejemplo, asumiendo que las dos JVMs se ejecutan sobre localhost, la configuración Apache-Tomcat debería tener algo como esto:

    
######################################################################
#      Apache-Tomcat with Same Machine JVM per Context               #
######################################################################
LoadModule jserv_module modules/ApacheModuleJServ.dll
<IfModule mod_jserv.c>
ApJServManual on
ApJServDefaultProtocol ajpv12
ApJServSecretKey DISABLED
ApJServMountCopy on
ApJServLogLevel notice

ApJServDefaultHost localhost
ApJServDefaultPort 8007

# Mounting the first context.
ApJServMount /joe ajpv12://localhost:8007/joe

# Mounting the second context.
ApJServMount /bill ajpv12://localhost:8009/bill
</IfModule>

Mirando al fichero de arriba podemos ver que tenemos dos puntos de montaje ApJServ explícitos, cada uno apuntando a un puerto diferente de la misma máquina. Esta claro que esta configuración requiere soporte desde la configuración encontrada en los ficheros server.xml. Necesitamos diferentes configuraciones de <Connector> en cada fichero para los diferentes procesos Tomcat. Realmente necesitamos dos ficheros server.xml diferentes (llamémosles server_joe.xml y server_bill.xml) con diferentes entradas <Connector> como se ve en los siguientes ejemplos:

    
<?xml version="1.0" encoding="ISO-8859-1"?>

<Server>
    <!-- Debug low-level events in XmlMapper startup -->
    <xmlmapper:debug level="0" />

    <!--  @@@
        Note, the log files are suffixed with _joe to distinguish
        them from the bill files. 
    -->

    <Logger name="tc_log" 
            path="logs/tomcat_joe.log"
            customOutput="yes" />

    <Logger name="servlet_log" 
            path="logs/servlet_joe.log"
            customOutput="yes" />

    <Logger name="JASPER_LOG" 
        path="logs/jasper_joe.log"
            verbosityLevel = "INFORMATION" />

    <!--  @@@
        Note, the work directory is suffixed with _joe to distinguish
        it from the bill work directory.
    -->
    <ContextManager debug="0" workDir="work_joe" >
        <!-- ==================== Interceptors ==================== -->

        ...
        
        <!-- ==================== Connectors ==================== -->

        ...

        <!-- Apache AJP12 support. This is also used to shut down tomcat.
          -->
        <!-- @@@ This connector uses port number 8007 for it's ajp communication -->
        <Connector className="org.apache.tomcat.service.PoolTcpConnector">
            <Parameter name="handler" 
       value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
            <Parameter name="port" value="8007"/>
        </Connector>
        
        <!-- ==================== Special webapps ==================== -->

        <!-- @@@ the /jow context -->
        <Context path="/joe" docBase="webapps/joe" debug="0" reloadable="true" > 
        </Context>
    </ContextManager>
</Server>       

Cuando miramos a server_joe.xml podemos ver que el <Connector> está configurado en el puerto 8007. Por otro lado, en server_bill.xml (ver abajo) el conector está configurado para el puerto 8009.

    
<?xml version="1.0" encoding="ISO-8859-1"?>

<Server>
    <!-- Debug low-level events in XmlMapper startup -->
    <xmlmapper:debug level="0" />

    <!--  @@@
        Note, the log files are suffixed with _bill to distinguish
        them from the joe files. 
    -->

    <Logger name="tc_log" 
            path="logs/tomcat_bill.log"
            customOutput="yes" />

    <Logger name="servlet_log" 
            path="logs/servlet_bill.log"
            customOutput="yes" />

    <Logger name="JASPER_LOG" 
        path="logs/jasper_bill.log"
            verbosityLevel = "INFORMATION" />

    <!--  @@@
        Note, the work directory is suffixed with _bill to distinguish
        it from the joe work directory.
    -->
    <ContextManager debug="0" workDir="work_bill" >

        <!-- ==================== Interceptors ==================== -->

        ...
        
        <!-- ==================== Connectors ==================== -->

        ...

        <!-- Apache AJP12 support. This is also used to shut down tomcat.
          -->
        <!-- @@@ This connector uses port number 8009 for it's ajp communication -->
        <Connector className="org.apache.tomcat.service.PoolTcpConnector">
            <Parameter name="handler" 
       value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
            <Parameter name="port" value="8009"/>
        </Connector>
        
        <!-- ==================== Special webapps ==================== -->
    
        <!-- @@@ the /bill context -->
        <Context path="/bill" docBase="webapps/bill" debug="0" reloadable="true" > 
        </Context>
    </ContextManager>
</Server>       

La configuración del puerto no es la únia diferencia entre los dos ficheros. Tenemos marcas @@@ en los cuatro lugares de los ficheros xml donde hemos realizado cambios. Como podemos ver, esta diferencia es necesaria para evitar que los dos procesos Tomcat sobreescriban los logs y el espacio de trabajo del otro.

Entonces deberíamos arrancar los dos procesos Tomcat usando el la opción -f de la línea de comando:

bin\startup -f conf\server_joe.xml

bin\startup -f conf\server_bill.xml

y luego accedemos a ellos desde Apache basándonos en los diferentes prefijos de las URLs del path.

. Configurar el Hosting Virtual

Es posible soportar host virtuales sobre Tomcat Ver3.2, de hecho la configuración de host virtuales es muy similar a la configuración para múltiples JVM y la razón es sencilla; en Tomcat 3.2 cada host virtual está implementado por un proceso Tomcat diferente.

Con la versión actual de Tomcat (Ver3.2), el hosting virtual sin preocupaciones está proporcionado por el servidor web (Apache/Netscape). El soporte de servidor de host virtual es usado por el adaptador Tomcat para redirigir las peticiones a cierto host virtual a la JVM(s) que conteine los contextos de este host virtual. Esto significa que si (por ejemplo) tenemos dos host virtuales (vhost1 y vhost2), tendremos dos JVMs: una ejecutándose en el contexto de vhost1 y la otra ejecutándose en el contexto de vhost2. Estas JVMs no se preocupan de la existencia de la otra, de hecho, no se preocupan del concepto de host virtual. Toda la lógica del hospedaje virtual está dentro del adaptador del servidor web. Para aclarar las cosas, veamos el siguiente fichero de configuración Apache-Tomcat

    
######################################################################
#        Apache Tomcat Virtual Hosts Sample Configuration            #
######################################################################
LoadModule jserv_module modules/ApacheModuleJServ.dll
<IfModule mod_jserv.c>
ApJServManual on
ApJServDefaultProtocol ajpv12
ApJServSecretKey DISABLED
ApJServMountCopy on
ApJServLogLevel notice

ApJServDefaultHost localhost
ApJServDefaultPort 8007

# 1 Creating an Apache virtual host configuration
NameVirtualHost 9.148.16.139

# 2 Mounting the first virtual host
<VirtualHost 9.148.16.139>
ServerName www.vhost1.com
ApJServMount /examples ajpv12://localhost:8007/examples
</VirtualHost>

# 3 Mounting the second virtual host
<VirtualHost 9.148.16.139>
ServerName www.vhost2.com
ApJServMount /examples ajpv12://localhost:8009/examples
</VirtualHost>
</IfModule>

Como podemos ver, los pasos 1, 2 y 3 definen dos host virtuales en Apache y cada uno de ellos monta el contexto /examples en cierta URL ajpv12. Cada URL ajpv12 apunta a una JVM que contiene el host virtual. La configuración de las dos JVM es muy similar a la mostrada en la sección anterior, y también necesitaremos usar dos ficheros server.xml diferentes (uno por cada host virtual) y necesitaremos arrancar los procesos Tomcat con la opción -f de la línea de comandos. Después de hacer esto podremos aproximarnos a Apache, cada vez con un nombre de host diferente, y el adaptador nos redirigirá la JVM apropiada.

La necesidad de mejorar el soporte para hosting virtual
Tener cada host virtual implementado por un JVM diferente es un enorme problema de escalabilidad. Las siguientes versiones de Tomcat haran posible soportar varios host virtuales en la misma JVM Tomcat.

. Trucos de Configuración del Mundo Real

Por defecto la distribución Tomcat viene con una configuración ingenua cuyo objetivo principal es ayudar al usuario recien experimentado y una operación "recién salido de la caja"... Sin embargo, esta configuración no es la mejor forma de desplegar Tomcat en sitios reales. Por ejemplo, los sites reales podrían requerir algún ajuste de rendimiento y configuraciones específicas de la site (elementos de path adicionales, por ejemplo). Esta sección intentará dirigirnos por los primeros pasos que deberíamos realizar antes de publicar una site basada en Tomcat.

. Modificar y Personalizar los Ficheros Batch

Como mencionamos en las secciones anteriores, los scripts de arrancada están para nuestra conveniencia. Aunque, algunas veces los scripts que necesitamos para desarrollar deberían ser modificados:

  • Para configurar los límites de recursos como el máximo número de descriptores.
  • Para añadir nuevas entradas en el CLASSPATH (por ejemplo, drivers JDBC).
  • Para añadir nuevas entradas en el PATH/LD_LIBRARY_PATH (por ejemplo, DLLs de drivers JDBC).
  • Para modificar las selecciones de la línea de comandos de la JVM.
  • Para asegurarnos de que estámos usando la JVM adecuada (de las dos o tres que podemos tener instaladas en nuestra máquina).
  • Para cambiar el usuario de root a algún otro usuario usando el comando "su" de UNIX.
  • Por cualquier otra razón.

Algunos de estos cambios se pueden hacer sin cambiar explícitamente los scripts básicos; por ejemplo, el script tomcat puede usar una variable de entorno llamada TOMCAT_OPTS para seleccionar los parámetros extras de la línea de comando de la JVM (como configuraciones de memoria, etc). Sobre UNIX también podemos crear un fichero llamando ".tomcatrc" en nuestro directorio home y Tomcat tomará la información de entorno como PATH, JAVA_HOME, TOMCAT_HOME y CLASSPATH desde este fichero. Sin embargo, sobre NT nos veremos forzados a reescrobor algunos de estos scripts de arrancada...

No tengas miedo, sólo hazlo!

. Modificar las Configuraciones por Defecto de la JVM

Las configuraciones por defecto de la JVM en el script tomcat son muy ingenuas; todo se deja por defecto. Hay algunas cosas que deberíamos considerar para mejorar el rendimiento de Tomcat:

  1. Modificar la configuración de memoria de nuestra JVM. Normalmente la JVM asigna un tamaño inicial para la pila Java y ya está, si necesitamos más memoria de está no podremos obtenerla.
    Además, en sitios sobrecargados, dar más memoria a la JVM mejora el rendimiento de Tomcat. Deberíamos usar los parámetros de la línea de comandos como -Xms/-Xmx/-ms/-mx para seleccionar los tamaños mínimo y máximo de la pila Java (y chequear si mejora el rendimiento).
  2. Modificar nuestra configuración de threading en la JVM. El JDK 1.2.2 para Linux viene con soporte para threads verdes y nativos. En general, los theads nativos son conocidos por proporcionar mejoras de rendimiento para aplicaciones que tratan con I/O, los threads verdes, por otro lado, ponen menos acento en la máquina. Deberíamos experimetnar con estos dos modelos de threads y ver cual es mejor para nuestra site (en general, los threads nativos son mejores).
  3. Seleccionamos la mejor JVM para la tarea. Hay distintos vendedores de JVMs por lo que deberemos decidirnos por la más rápida o la más barata, según nos interese

. Modificar nuestros Conectores

Los conectores, según los configura el fichero server.xml de Tomcat, contiene dos Connectors configurados como en el siguiente fragmento:

        <!-- (1) HTTP Connector for stand-alone operation -->
        <Connector className="org.apache.tomcat.service.PoolTcpConnector">
            <Parameter name="handler"
                value="org.apache.tomcat.service.http.HttpConnectionHandler"/>
            <Parameter name="port"
                value="8080"/>
        </Connector>

        <!-- (2) AJPV12 Connector for out-of-process operation -->
        <Connector className="org.apache.tomcat.service.PoolTcpConnector">
            <Parameter name="handler"
                value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
            <Parameter name="port"
                value="8007"/>
        </Connector>
  1. Es un conector que escucha en el puerto 8080 para peticiones HTTP entrantes. Este conector es necesario para operaciones independientes.
  2. Es un conector que escucha en el puerto 8007 para peticiones AJPV12 entrantes. Este conector es necesario para la integración del servidor web (integración de servlets fuera-de-proceso).

El conector AJPV12 es necesario para cerrar Tomcat. Sin embargo, el conector HTTP podría eliminarse si la operación independiente no lo necesitase.

. Usar Almacenes de Threads en nuestros Conectores

Tomcat es un contenedor servlet multi-thread lo que significa que cada petición necesita ser ejecutada por algún thread. Anteriomente a Tomcat 3.2, por defecto había que crear un nuevo thread para servir cada petición que llegaba. Este comportamiento era problemático en sitios sobrecargados porque:

  • Arrancar y parar un thread para cada petición pone en aprietos al sistema operativo y a la JVM.
  • Es dificil limitar el consumo de recursos. Si llegan 300 peticiones de forma concurrente Tomcat abrirá 300 threads para servirlas y asignará todos los recursos necesarios para servir las 300 peticiones al mismo tiempo. Esto hace que Tomcat asigne muchos más recursos (CPU, Memoria, Descriptores...) de lo que debiera y puede bajar el rendimiento e incluso colgarse si los recursos están exhaustos.

La solución para estos problemas es usar un thread pool (almacen de threads), que se usa por defecto en Tomcat 3.2. Los contenedores Servlets que usan almacenes de threads se liberan a sí mismos de manejar sus treads. En lugar de asignar nuevos threads, cada vez que los necesitan, se los piden al almacen, y cuando todo está hecho, el thread es devuelto al almacen. Ahora el almacen de threads se puede utilizar para implementar técnicas de control de de threads, como:

  1. Mantener threads "abiertos" y reutilizarlos una y otra vez. Esto nos evita el problema asociado con la creación y destrucción continua de threads.
    • Normalmente el administrador puede instruir al almacen para que no mantenga demasiados threads desocupados, liberándolos si es necesario.
  2. Seleccionando un límite superior en el número de threads usados de forma concurrente. Esto evita el problema de la asignación de recursos asociada con la asignación ilimitada de threads.
    • Si el contenedor alcanza su límite superior de threads, y llega una nueva petición, esta nueva petición tendrá que esperar hasta que alguna otra petición (anterior) termine y libere el thread que está usando.

Podemos refinar las técnicas descritas arriba de varias formas, pero sólo serán refinamientos. La principal contribución de los almacenes de threads es la reutilización de los thrreads un límite superior que limite el uso de recursos.

Usar un almacen de threads en Tomcat es un sencillo movimiento; todo lo que necesitamos hacer es usar un PoolTcpConnector en nuestra configuración de <Connector>. Por ejejmplo, el siguiente fragmento de server.xml define ajpv12, como un conector con almacen:

        <!-- A pooled AJPV12 Connector for out-of-process operation -->
        <Connector className="org.apache.tomcat.service.PoolTcpConnector">
            <Parameter
                name="handler"
                value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
            <Parameter
                name="port"
                value="8007"/>
        </Connector>

Este fragmento es muy simple y el comportamiento (por defecto) del almacen instruido por él es:

  • Un límite de 50 threads concurrentes..
  • Cuando el almacen tenga más de 25 threads desocupados empezará a eliminarlos.
  • El almacen empezará con la creación de 10 threads, y tratará de mantener 10 threads vacantes (mientras no llegue al límite superior)

La configuración por defecto está bien para sites de media carga con un media de 10-40 peticiones concurrentes. Si nuestro site es diferente deberíamos modificar esta configuración (por ejemplo reduciendo el límite superior). La configuración del almacen de threads se puede hacer desde el elemento <Connector> en server.xml como se demuestra en el siguiene fragmento:

        <!-- A pooled AJPV12 Connector for out-of-process operation -->
        <Connector className="org.apache.tomcat.service.PoolTcpConnector">
            <Parameter
                name="handler"
                value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
            <Parameter
                name="port"
                value="8007"/>
            <Parameter
                name="max_threads"
                value="30"/>
            <Parameter
                name="max_spare_threads"
                value="20"/>
            <Parameter
                name="min_spare_threads"
                value="5" />
        </Connector>

Como se puede ver el almacen tiene 3 parámetros de configuración:

  • max_threads - define el límite superior de concurrencia, el almacen no creará más de este número de threads.
  • max_spare_threads - define el máximo número de threads que el almacen mantendrá inactivos. Si el número de threads inactivos excede este valor los eliminará.
  • min_spare_threads - el almacen intentará asegurarse de que en todo momemto hay al menos este número de threads inactivos esperando que lleguen nuevas peticiones. min_spare_threads debe ser mayor que 0.

Deberíamos usar estos parámetros para ajustar el comportamiento del almacen a nuestras necesidades.

. Desactivar la Auto-Recarga de Servlets

La auto-recarga de servlets es muy util en el momento del desarrollo. Sin embargo es muy costosa (en términos de degradación del rendimiento) y podría poner a nuestra aplicación en extraños confilctos cuando las clases fueran cargadas y ciertos cargadores de clases no puedieran cooperar con las clases cargadas por el classloader actual.

Por eso, a menos que tengamos una necesidad real para recargar las clases durante el despliegue deberíamos desactivar la bandera reloadable en nuestros contextos.

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.