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:
- 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: - 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 - 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.
- En Win32 deber�amos teclear:
set TOMCAT_HOME=foo\jakarta-tomcat-3.2.1
- Sobre UNIX deber�amos teclear:
para bash/sh:TOMCAT_HOME=foo/jakarta-tomcat-3.2.1 ; export TOMCAT_HOME
para tcshsetenv TOMCAT_HOME foo/jakarta-tomcat-3.2.1
- En Win32 deber�amos teclear:
- 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 |
|
Win32 |
|
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:
- server.xml - El fichero de configuraci�n golbal de Tomcat.
- 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:
- Proporcionar configuraci�n inicial para los componentes de Tomcat.
- 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:
|
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:
|
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:
|
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:
- Tomcat no es tan r�pido como Apache cuando sirve p�ginas est�ticas.
- Tomcat no es tan configurable como Apache.
- Tomcat no es tan robusto como Apache.
- 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:
- Cubriremos el comportamiento fundamental de un servidor web.
- Explicaremos la configuraci�n que necesitamos.
- 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:
- 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.
- 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.
- 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.
- 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:
- Descargar la distribuci�n fuente de Tomcat desde http://jakarta.apache.org/downloads/sourceindex.html.
- Descomprimirla en alg�n directorio.
- 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:
- Descargar la distribuci�n fuente de Tomcat desde http://jakarta.apache.org/downloads/sourceindex.html.
- Descomprimirla en alg�n directorio.
- 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:
- Podr�amos querer configurar Tomcat bas�ndonos en la seguridad para esos recursos.
- 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:
- Instruir a Apache para que env�e todas la peticiones servlet a Tomcat
- 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:
- 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.
- 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.
- 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.
- 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.
- 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.
- 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:
- 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). - 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).
- 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>
- Es un conector que escucha en el puerto 8080 para peticiones HTTP entrantes. Este conector es necesario para operaciones independientes.
- 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:
- 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.
- 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.