# Tomcat ## 1. Aplicaciones Web y servidores de aplicaciones **!IMPORTANTE** Un servidor de aplicaciones es un software que proporciona aplicaciones a los equipos o dispositivos cliente, por lo general, a través de Internet y utilizando el protocolo HTTP. Los servidores de aplicación se distinguen de los servidores web en el uso extensivo del contenido dinámico y por su frecuente integración con bases de datos. Un servidor de aplicaciones también es una máquina en una red de computadores que ejecuta determinadas aplicaciones, gestionando la mayor parte de las funciones de acceso a los datos de la aplicación. Las principales ventajas de la tecnología de los servidores de aplicaciones es **la centralización y disminución de la complejidad en el desarrollo de las aplicaciones**, ya que no necesitan ser programadas, sino que son ensambladas desde bloques provistos por el servidor de aplicación. Otra de las ventajas es la **integridad de datos y código** ya que, al estar centralizada en una o un pequeño número de máquinas servidoras, las actualizaciones están garantizadas para todos los usuarios. ### El servidor de aplicaciones Tomcat Tomcat es el servidor web (incluye el servidor Apache) y de aplicaciones del proyecto Yakarta, con lo cual, gestiona las solicitudes y respuestas HTTP y, además, es servidor de aplicaciones o contenedor de Servlets y JSP. **!IMPORTANTE** Incluye el compilador Jasper, que compila JSP covirtiéndolas en servlets. 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 en el que se usa un servidor web basado en Java. Por defecto Tomcar trabaja en este modo. 2. **Contenedores de servlets dentro-de-proceso**: El contenedor servlets es una combinación de un plugin para el servidor web y una implementación de contenedor Java. El plugin 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. En el caso de que una petición debiera 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 servlets 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 tuviese que ejecutar un servlets, 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 soporta los servidores Apache, IIS). ### Instalación y Configuración Básica (Pasos mas importantes) En primer lugar, destacar que para instalar cualquier versión de Tomcat es necesario tener instalado JDK (Kit de desarrollo de Java). Instalamos el siguiente paquete por ser el que más se adapta a nuestras necesidades: ```bash= $sudo apt install default-jdk ``` Ahora tenemos que crear el archivo tomcat.service en el directorio /etc/systemd/system: ```bash= $sudo nano /etc/systemd/system/tomcat.service ``` *tomcat.service* ```bash= [Unit] Description=Apache Tomcat Web Application Container After=network.target [Service] Type=forking Environment=JAVA_HOME=/usr/lib/jvm/java-1.11.0-openjdk-amd64 Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid Environment=CATALINA_HOME=/opt/tomcat Environment=CATALINA_BASE=/opt/tomcat Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC' Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom' ExecStart=/opt/tomcat/bin/startup.sh ExecStop=/opt/tomcat/bin/shutdown.sh User=tomcat Group=tomcat UMask=0007 RestartSec=10 Restart=always [Install] WantedBy=multi-user.target ``` Por último, recargamos el demonio systemd para que reciba información sobre nuestro archivo de servicio e iniciamos el servicio Tomcat: ```bash= $sudo systemctl daemon-reload $sudo systemctl start tomcat ``` En Tomcat, la gestión del servicio se realiza a través del script incluido llamado catalina, al que le podemos proporcionar los parámetros start y stop, con lo que arrancaríamos o pararíamos el servicio manualmente. Para comprobar que nuestro servidor está ya escuchando, introducimos en un navegador la URL: http://localhost:8080 o http://127.0.0.1:8080. ### Iniciar Tomcat Tomcat va a estar escuchando en el puerto 8080 y va a tener su propio directorio de trabajo. La misión de apache2 va a ser interceptar todas las peticiones en el puerto 80 y derivar las que considere necesarias a Tomcat; de este modo observamos la ventaja de la escalabilidad. Apache por defecto busca los ficheros en /var/www/html, Tomcat trabaja sobre la carpeta /opt/tomcat/webapps. La petición de una URL se puede gestionar, parte por apache y parte por Tomcat, por lo que vamos a cambiar la carpeta por defecto de trabajo para unificarlo. Para ello editamos el fichero /opt/tomcat/conf/conf/server.xml. ```bash= $sudo nano /opt/tomcat/conf/server.xml ``` en donde encontraremos una línea con "Host name=" y debería tener: ```bash= Host name=”localhost” appBase=”wwebapps" ``` Para usar la aplicación de administración web que viene con Tomcat, debemos añadir un inicio de sesión a nuestro servidor de Tomcat. Para ello editaremos el archivo tomcat-users.xml: ```bash= $sudo nano /opt/tomcat/conf/tomcat-users.xml ``` Deberíamos añadir un usuario que pueda acceder a manager-gui y admin-gui (aplicaciones web que vienen con Tomcat). Podemos definir un usuario, por ejemplo como el que se muestra a continuación, entre las etiquetas tomcat-users, y poniendo nombres de usuarios y contraseñas seguras: ```xml= <tomcat-users . . .> <user username="admin" password="password" roles="manager-gui,admin-gui"/> </tomcat-users> ``` Si en cualquier momento deseásemos parar o arrancar el servidor, podríamos emplear los siguientes comandos respectivamente: ```bash= $sudo systemctl stop tomcat # o $sudo service tomcat stop $sudo systemctl start tomcat # o $sudo service tomcat start ``` ## Implantación de arquitecturas web. Una aplicación web está compuesta de una serie de servlets, páginas JSP, ficheros HTML, ficheros de imágenes, ficheros de sonidos, texto, clases, etc.; de forma que todos estos recursos se pueden empaquetar y ejecutar en varios contenedores distintos. Un servlet es una aplicación java encargada de realizar un servicio específico dentro de un servidor web. La especificación Servlet 2.2 define la estructura de directorios para los ficheros de una aplicación web. El directorio raíz debería tener el nombre de la aplicación y define la raíz de documentos para la aplicación web. Todos los ficheros debajo de esta raíz pueden servirse al cliente excepto aquellos ficheros que están bajo los directorios especiales META-INF y WEB-INF en el directorio raíz. Todos los ficheros privados, al igual que los ficheros .class de los servlets, deberían almacenarse bajo el directorio WEB-INF. Durante la etapa de desarrollo de una aplicación web se emplea la estructura de directorios, a pesar de que luego en la etapa de producción, toda la estructura de la aplicación se empaqueta en un archivo .war. De forma genérica podríamos decir que una aplicación web se estructura en tres capas: 1. Navegador web. 2. Tecnología web dinámica (PHP, Java Servlets, ASP, etc.) 3. Base de datos encargada de almacenar de forma permanente y actualizada la información que la aplicación web necesita. ### Archivos WAR **!IMPORTANTE** Su nombre procede de Web Application Archive (Archivo de Aplicación Web); permiten empaquetar en una sola unidad aplicaciones web de Java completas, es decir que su contenido sea: 1. Servlets y JSP. 2. Contenido estático: HTML, imágenes, etc. 3. Otros recursos web. Su estructura es la siguiente: 1. **/**: En la carpeta raíz del proyecto se almacenan elementos empleados en los sitios web: documentos html, hojas de estilo y los elementos JSP (*.html, *.jsp, *.css). 2. **/WEB-INF/**: Aquí se encuentran los elementos de configuración del archivo .war como pueden ser: la página de inicio, la ubicación de los servlets, parámetros adicionales para otros componentes. El más importante de éstos es el archivo web.xml. 3. **/WEB-INF/classes/**: Contiene las clases Java empleadas en el archivo .war y, normalmente, en esta carpeta se encuentran los servlets. 4. **/WEB-INF/lib/**: Contiene los archivos JAR utilizados por la aplicación y que normalmente son las clases empleadas para conectarse con la base de datos o las empleadas por librerías de JSP. Para generar archivos .war se pueden emplear diversas herramientas desde entorno IDE. Por ejemplo, encontramos: NetBeans y Eclipse, ambos Open-Source y también Jbuilder de Borland, Jdeveloper de Oracle; otro modo de construir archivos .war es mediante Ant. > Pregunta: Un archivo .WAR ... > - [ ] Es un archivo comprimido que se puede generar con cualquier tipo de compresor, por ejemplo winzip, winrar, tar, etc. > - [ ] Es una aplicación web formada únicamente por archivos .html. > - [x] Es un archivo en el cual se empaqueta en una sola unidad, aplicaciones web completas. > - [ ] Es un archivo que engloba el protocolo de comunicación de las aplicaciones web generadas con Java. ### Despliegue de aplicaciones con Tomcat **!IMPORTANTE** Una aplicación web puede ser desplegada empleando uno de los siguientes métodos: 1. Por medio de archivos .war (Web Archive). 2. Editando los archivos **web.xml** y server.xml. Este método es el que se pasa a tratar a continuación. Los directorios que forman una aplicación compilada suelen ser : www, bin, src, tomcat y gwt-cache. La carpeta www contiene, a su vez, una carpeta con el nombre y ruta del proyecto que contiene los ficheros que forman la interfaz (.html, .js, .css, etc.). La carpeta bin contiene las clases de java de la aplicación. ## 2. Despliegue de aplicaciones en Tomcat **!IMPORTANTE** Desplegar un servlet consiste en situar una serie de archivos en un contenedor web para que los clientes puedan acceder a su funcionalidad; una aplicación web es un conjunto de servlets que se pueden empaquetar de una forma determinada. Una aplicación web puede ser desplegada en diferentes servidores web manteniendo su funcionalidad y sin ningún tipo de modificación en su código debido a la especificación servlet 2.2. Las aplicaciones web deben organizarse según la siguiente estructura de directorios: - Directorio principal (raíz): Contendrá los ficheros estáticos (HTML, imágenes, etc...) y JSPs. - Carpeta WEB-INF: contiene el fichero "web.xml" (descriptor de la aplicación), encargado de configurar la aplicación. - Subcarpeta classes: contiene los ficheros compilados (servlets, beans). - Subcarpeta lib: librerías adicionales. - Resto de carpetas para ficheros estáticos. Una aplicación web puede ser desplegada empleando uno de los siguientes métodos: - Por medio de archivos WAR. - Editando los archivos web.xml y server.xml. Los directorios que forman una aplicación compilada suelen ser: www, bin, src, tomcat, gwt-cache. Para desplegar la aplicación en Tomcat se deben realizar los siguientes pasos: 1. Copiar la carpeta contenida en www (con el nombre del proyecto) en el directorio webapps de Tomcat. 2. Renombrar la nueva carpeta creada en Tomcat con un nombre más sencillo. 3. Crear, dentro de dicha carpeta, otra nueva, y darle el nombre WEB-INF. 4. Crear, dentro de WEB-INF, otros dos subdirectorios, llamados lib y classes. 5. Copiar en lib todas las librerías (.jar) que necesite la aplicación para su funcionamiento. 6. Copiar el contenido de la carpeta bin de la aplicación en el subdirectorio WEB-INF/classes del Tomcat. 7. Crear en WEB-INF un fichero de texto llamado web.xml, con las rutas de los servlets utilizados en la aplicación. 8. Ya puede accederse a la aplicación en el servidor, el modo de hacerlo es poniendo en el navegador la ruta del fichero HTML de entrada, que estará ubicado en la carpeta de la aplicación en Tomcat. 9. Vamos a partir de una máquina con el sistema operativo Ubuntu 20.04, debido a que pretendemos montar una plataforma LAMP, instalaremos también los siguientes componentes: MySql y PHP. Recordemos que para instalar cualquier versión de Tomcat es necesario tener instalado JDK (Kit de desarrollo de Java), ya que el objetivo es que las peticiones a Apache se redirijan a Tomcat empleando un conector proporcionado por Java en este caso. ### Creación de una aplicación web El servidor de aplicaciones Tomcat cuenta con una serie de ejemplos, tanto de servlets como de JSP, que sirven de ayuda para aprender a realizar las tareas creación y despliegue de aplicaciones web. Es muy interesante crear dos variables de entorno: JAVA_HOME que indique la ubicación de los archivos binarios de Java y CATALINA_HOME que apunta a la ubicación de los scripts de Tomcat. **!!** Los WARs simplemente son archivos Java de una aplicación web con una extensión diferente para diferenciarlos de los comunmente usados JARs. Antes de la especificación Servlet 2.2, era bastante diferente desplegar servlets entre diferentes contenedores de servlets, anteriormente también llamados motores servlet. La especificación 2.2 estandarizó el despliegue entre contenedores, llevando así la portabilidad del código Java un paso más allá. El método más sencillo para desplegar una aplicación, que sobre todo se utiliza durante la etapa de desarrollo de la misma, copiar la carpeta correspondiente a nuestra aplicación en la carpeta $CATALINA_HOME/webapps, teniendo en cuenta que la variable $CATALINA_HOME es la ruta de los scripts que emplea Tomcat. **!!** Una vez consideramos terminada nuestra aplicación web podremos generar el archivo .WAR perteneciente a la aplicación, para ello podemos aplicar los siguentes comandos: - **javac -d WEB-INF/classes \*.java** este comando tiene como finalidad la compilación de las clases Java de nuestra aplicación. - **jar cvf Aplic_Web.war \*** para crear el archivo .WAR. Una vez hecho lo anterior podríamos acceder vía web a: http://127.0.0.1:8080 y, en el apartado "Administration", accedemos a la opción "Tomcat Manager". ### Implementar el registro de acceso Las válvulas del Tomcat son una tecnología introducida a partir de Tomcat 4 que permite asociar una instancia de una clase Java a un contenedor "Catalina". Esta configuración permite que la clase asociada actúe como un pre-procesador de las peticiones. Estas clases se llaman válvulas, y deben implementar la interfaz "org.apache.catalina.Valve" interface o extender de la clase "org.apache.catalina.valves.ValveBase". Las válvulas son propias de Tomcat y no pueden ser usadas en otros contenedores de servlet. Las válvulas disponibles son: - **Access Log Valve**: está implementada por la clase org.apache.catalina.valves.AccessLogValve. Crea ficheros de log para rastrear el acceso a la información de los clientes, registrando información como, por ejemplo, actividad de la sesión del usuario, información de la autenticación del usuario, entre otras. Indicará que los logs de acceso se almacenarán en el directorio $CATALINA_HOME/logs y los archivos de log tendrán la nomenclatura con prefijo: localhost_access_log y sufijo .txt probablemente entre sufijo y prefijo se añadirá la fecha en la que se crea dicho archivo. - **Remote Address Filter**: permite comparar la dirección IP del cliente con una o más expresiones regulares y, como resultado de ello, denegar o bien permitir la solicitud presentada por el cliente. - **Remote Host Filter**: es muy parecido al anterior pero con la diferencia que permite comparar por nombre de equipo en lugar de IP. - **Request Dumper**: es una herramienta de depuración que escribe en el log el detalle de cada petición realizada. Cualquier acceso a localhost:8080 tendrá asociado una serie de entradas en los logs. - **Single Sign On**: cuando queremos que los usuarios puedan identificarse en cualquier aplicación de nuestro virtual host, y que su identidad sea reconocida por cualquier aplicación que esté en ese host. ### Sesiones persistentes Las sesiones activas por parte de clientes a aplicaciones web alojadas en servidores web Tomcat, por defecto, están configuradas para mantenerse en caso de posibles pérdidas de conexión con el servidor o posibles reinicios del mismo; a pesar de todo ello es posible establecer un control mayor sobre dichas sesiones. Por lo que respecta a las sesiones inactivas (pero todavía no caducadas) es posible configurarlas de forma que se almacenen en disco liberando, como consecuencia de ello, los recursos de memoria asociados. Al parar Tomcat las sesiones activas se vuelcan a disco de manera que, al volver a arrancarlo, se podrán restaurar. Las sesiones con un tiempo de vida que supere un límite se copian automáticamente a disco por seguridad para evitar posibles bloqueos de sesión. Para configurar las sesiones persistentes tendremos que gestionar el elemento <Manager> como un subelemento de <Context> de forma que podemos actuar a dos niveles en función de si pretendemos que la configuración establecida se aplique a todas las aplicaciones del servidor o a una aplicación concreta. Si configuramos las sesiones persistentes de forma global tenemos que manipular el archivo /conf/context.xml, mientras que si queremos configurar las sesiones a nivel local a una aplicación web determinada tendríamos que adaptar el archivo <CATALINA_HOME>/conf/context.xml correspondiente a la aplicación. ### Configurar Tomcat en cluster Debido al incremento de las aplicaciones web, la escalabilidad y la disponibilidad se transforma en un recurso transcendental para garantizar el servicio eficiente a los clientes web; la implementación de clustering para los servidores de aplicaciones web es una solución eficaz y relativamente sencilla. La implementación de clustering con Tomcat provee: - **Escalibilidad**: escalado horizontal (implica el incremento del número de servidores), escalado vertical (implica el incremento de los recursos del propio servidor). - **Alta disponibilidad**: Tomcat provee failover; en el motor del servidor existen dos tipos de failover provistos por clustering: - **Request-level failover**: Si un servidor cae, los siguientes requerimientos se redireccionarán a otros servidores activos. - **Session-level failover**: En el caso de que un servidor deje de dar servicio, otro servidor del cluster debería proporcionar la sesión a los clientes consiguiendo reducir al mínimo la pérdida de conexión, ello implica replicar la sesión en el cluster en la nueva máquina en el mínimo tiempo posible. - **Balanceo de carga**: establecer un método de reparto de la carga de peticiones entre los servidores del cluster, de modo que se minimice el tiempo de respuesta a las solicitudes de los clientes; se consigue empleando algoritmos de distribución de carga. Las soluciones de clustering típicas ofrecen un paradigma de servidor que consiste en ofrecer un sistema basado en ejecución distribuida, a pesar de que existe limitación respecto a la escalabilidad, podemos observar el esquema de Jakarta Tomcat server engine works. El conector del servidor de cluster recibe la petición desde los clientes, y el procesador del servidor de cluster encapsula las peticiones en los objetos "RequestEntry" y los escribe en JavaSpace. El conector del Worker del cluster toma dichas peticiones y el procesador del worker del cluster resuelve las peticiones. Para establecer una configuración de cluster en Tomcat podremos seguir los siguientes pasos: - Todos los atributos de sesion deben implementar java.io.Serializable. - Descomentar el elemento Cluster en server.xml. - Descomentar Valve (ReplicationValve) en server.xml - Si las múltiples instancias de Tomcat están en la misma máquina el parámetro tcpListenPort tiene que ser único para cada una de las instancias. - Establecer en el archivo web.xml el elemento <distributable/> o bien definirlo de forma <Context distributable="true"/>. - El atributo jvmRoutes tiene que estar definido en el "Engine" <Engine name="Catalina" jvmRoute="nodeX"> estableciendo su valor al nombre de la instancia en el cluster. - Sincronizar la hora de todos los nodos con un servicio NTP. - Configurar el parámetro loadbalancer en modo "sticky session". ### EAR ![](https://i.imgur.com/5eul7FY.png) ### JSP ![](https://i.imgur.com/Yy4pygF.png) ###### tags: `DAW` `DPL` `UT6`