Migración de aplicaciones de Tomcat a Tomcat en Azure App Service
En esta guía se describe lo que hay que tener en cuenta para migrar una aplicación de Tomcat existente para que se ejecute en Azure App Service mediante Tomcat 9.0.
Antes de la migración
Para asegurarse de que la migración se realiza correctamente, antes de empezar, complete los pasos de evaluación e inventario descritos en las secciones siguientes.
Si no puede cumplir alguno de los requisitos previos a la migración, consulte las siguientes guías de migración complementarias:
- Migración de aplicaciones de Tomcat a contenedores en Azure Kubernetes Service
- Migración de aplicaciones de Tomcat a Azure Virtual Machines (planeada)
Cambio a una plataforma compatible
App Service ofrece versiones específicas de Tomcat en versiones específicas de Java. Para garantizar la compatibilidad, migre la aplicación a una de las versiones de Tomcat y Java admitidas en su entorno actual antes de continuar con los pasos restantes. Asegúrese de probar por completo la configuración resultante. Use la versión estable más reciente de la distribución de Linux en dichas pruebas.
Nota:
Esta validación es especialmente importante si el servidor actual se está ejecutando en un JDK no compatible (como Oracle JDK o IBM OpenJ9).
Para obtener la versión actual de Java, inicie sesión en el servidor de producción y ejecute el siguiente comando:
java -version
En Azure App Service, los binarios para Java 8 se proporcionan desde Eclipse Temurin. Para Java 11, 17 y todas las futuras versiones LTS de Java, App Service proporciona Microsoft Build of OpenJDK. Estos archivos binarios están disponibles para su descarga gratuita en los siguientes sitios:
Para obtener la versión actual de Tomcat, inicie sesión en el servidor de producción y ejecute el siguiente comando:
${CATALINA_HOME}/bin/version.sh
Para obtener la versión actual que usa Azure App Service, descargue Tomcat 9, en función de la versión que vaya a usar en Azure App Service.
Recursos externos de inventario
Los recursos externos, tales como los orígenes de datos, los agentes de mensajes JMS y otros, se insertan a través de la interfaz de directorio y nomenclatura de Java (JNDI). Algunos de estos recursos pueden requerir una migración o reconfiguración.
Dentro de la aplicación
Inspeccione el archivo META-INF/context.xml. Busque elementos <Resource>
dentro del elemento <Context>
.
En los servidores de aplicaciones
Inspeccione los archivos $CATALINA_BASE/conf/context.xml y $CATALINA_BASE/conf/server.xml, así como los archivos .xml que se encuentran en los directorios $CATALINA_BASE/conf/[nombreDelMotor]/[nombreDelHost].
En los archivos context.xml, los recursos de JNDI se describen con los elementos <Resource>
que están dentro del elemento <Context>
de nivel superior.
En los archivos server.xml, los recursos de JNDI se describen con los elementos <Resource>
que están dentro del elemento <GlobalNamingResources>
.
Orígenes de datos
Los orígenes de datos son recursos de JNDI con el atributo type
con el valor javax.sql.DataSource
. Para cada origen de datos, documente la siguiente información:
- ¿Cuál es el nombre del origen de datos?
- ¿Cuál es la configuración del grupo de conexiones?
- ¿Dónde puedo encontrar el archivo JAR del controlador JDBC?
Para más información, consulte los artículos de procedimientos de los orígenes de datos JNDI en la documentación de Tomcat.
Todos los demás recursos externos
No es factible documentar todas las dependencias externas posibles en esta guía. Es responsabilidad del equipo comprobar que puede cumplir todas las dependencias externas de la aplicación después de la migración.
Secretos de inventario
Contraseñas y cadenas seguras
Compruebe las cadenas secretas y las contraseñas en todas las propiedades y los archivos de configuración de los servidores de producción. Asegúrese de comprobar los archivos server.xml y context.xml en $CATALINA_BASE/conf. También puede encontrar archivos de configuración que contengan contraseñas o credenciales dentro de la aplicación. Estos pueden ser archivos META-INF/context.xml y, para las aplicaciones de Spring Boot, archivos application.properties o application.yml.
Certificados de inventario
Documente todos los certificados utilizados para los puntos de conexión SSL públicos o la comunicación con las bases de datos de backend y otros sistemas. Para ver todos los certificados de los servidores de producción, ejecute el siguiente comando:
keytool -list -v -keystore <path to keystore>
Determinación de si se usa el sistema de archivos y cómo
Para usar el sistema de archivos en el servidor de aplicaciones será necesario cambiar la configuración o, en raras ocasiones, la arquitectura. Puede identificar algunos o todos los escenarios siguientes.
Contenido estático de solo lectura
Si su aplicación actualmente sirve contenido estático, necesitará una ubicación alternativa para él. Quizás quiera considerar la posibilidad de mover el contenido estático a Azure Blob Storage y agregar Azure CDN para tener descargas de alta velocidad globalmente. Para más información, consulte Hospedaje de sitios web estáticos en Azure Storage e Inicio rápido: Integración de una cuenta de una instancia de Azure Storage con Azure CDN.
Contenido estático publicado dinámicamente
Si su aplicación permite que haya contenido estático que la aplicación carga o produce, pero que es inmutable una vez creado, puede usar Azure Blob Storage y Azure CDN con una función de Azure para controlar las cargas y la actualización de la red CDN. Hemos proporcionado una implementación de ejemplo para su uso en Cargar y carga previa en CDN de contenido estático con Azure Functions.
Contenido dinámico o interno
En el caso de los archivos que la aplicación lee y escribe con frecuencia (por ejemplo, los archivos de datos temporales) o los archivos estáticos que solo son visibles para la aplicación, puede montar recursos compartidos de Azure Storage en el sistema de archivos de App Service. Para obtener más información, consulte Montaje de Azure Storage como un recurso compartido local en App Service.
Identificación del mecanismo de persistencia de sesión
Para identificar el administrador de persistencia de sesión que se está usando, inspeccione los archivos context.xml de la aplicación y la configuración de Tomcat. Busque el elemento <Manager>
y, a continuación, anote el valor del atributo className
.
Las implementaciones integradas de PersistentManager de Tomcat, como StandardManager o FileStore no están diseñadas para usarse con una plataforma distribuida y escalada como App Service. Como App Service puede equilibrar la carga entre varias instancias y reiniciar de forma transparente cualquier instancia en cualquier momento, por lo que no se recomienda conservar el estado mutable en un sistema de archivos.
Si se necesita la persistencia de la sesión, deberá usar una implementación de PersistentManager
alternativa que escribirá en un almacén de datos externo, como VMware Tanzu Session Manager con Redis Cache. Para más información, consulte Uso de Redis como caché de sesión con Tomcat.
Identificación de todos los procesos externos y los demonios que se ejecutan en los servidores de producción
Si tiene procesos que se ejecutan fuera del servidor de aplicaciones, como los demonios de supervisión, tendrá que eliminarlos o migrarlos a otro lugar.
Casos especiales
Algunos escenarios de producción pueden requerir otros cambios o imponer limitaciones adicionales. Aunque estos escenarios no son frecuentes, es importante asegurarse de que no son aplicables a la aplicación o que se han resuelto correctamente.
Determinación de si la aplicación se basa en trabajos programados
Los trabajos programados, como las tareas del programador de Quartz o los trabajos de cron, no se pueden usar con App Service. App Service no le impedirá implementar internamente una aplicación que contenga tareas programadas. Sin embargo, si la aplicación se escala horizontalmente, un mismo trabajo programado se podría ejecutar más de una vez por cada período programado. Esta situación puede tener consecuencias no deseadas.
Haga un inventario de todos los trabajos programados, dentro o fuera del servidor de aplicaciones.
Determinación de si la aplicación contiene código específico del sistema operativo
Si la aplicación contiene código con dependencias en el sistema operativo del host, deberá refactorizarla para quitar esas dependencias. Por ejemplo, es posible que tenga que reemplazar cualquier uso de /
o \
en las rutas del sistema de archivos con File.Separator
o Paths.get
si la aplicación se ejecuta en Windows.
Determinación de si se utiliza la agrupación en clústeres de Tomcat
Azure App Service no admite la agrupación en clústeres de Tomcat. En su lugar, puede configurar y administrar el equilibrio de carga y el escalado mediante Azure App Service sin la funcionalidad específica de Tomcat. Puede conservar el estado de la sesión en una ubicación alternativa para que esté disponible en todas las réplicas. Para más información, consulte Identificación del mecanismo de persistencia de sesión.
Para determinar si la aplicación usa la agrupación en clústeres, busque el elemento <Cluster>
dentro de los elementos <Host>
o <Engine>
del archivo server.xml.
Determinación de si se usan conectores que no son HTTP
App Service solo admite un conector HTTP. Si la aplicación requiere otros conectores, como el conector de AJP, no utilice App Service.
Para identificar los conectores HTTP que usa la aplicación, busque elementos <Connector>
dentro del archivo server.xml en la configuración de Tomcat.
Determinación de si se usa MemoryRealm
MemoryRealm requiere un archivo XML persistente. En Azure App Service, tendrá que cargar este archivo en el directorio /home, o en uno de sus subdirectorios, o en el almacenamiento montado. Tendrá que modificar el parámetro pathName
como corresponda.
Para determinar si MemoryRealm
se usa actualmente, inspeccione los archivos server.xml y context.xml y busque elementos <Realm>
en los que el atributo className
esté establecido en org.apache.catalina.realm.MemoryRealm
.
Determinación de si se utiliza el seguimiento de sesión SSL
App Service realiza la descarga de la sesión fuera del entorno de ejecución de Tomcat, por lo que no se puede usar el seguimiento de sesión SSL. En su lugar, use otro modo de seguimiento de sesión (COOKIE
o URL
). Si necesita el seguimiento de sesión SSL, no utilice App Service.
Determinación de si se usa AccessLogValve
Si usa AccessLogValve, debe establecer el parámetro directory
en /home/LogFiles
o en uno de sus subdirectorios.
Migración
Parametrización de la configuración
En los pasos previos de la migración, es probable que haya identificado secretos y dependencias externas, como orígenes de bits, en los archivos server.xml y context.xml. En cada elemento identificado, reemplace los nombres de usuario, contraseñas, cadenas de conexión o direcciones URL por una variable de entorno.
Por ejemplo, supongamos que el archivo context.xml contiene el siguiente elemento:
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="jdbc:postgresql://postgresdb.contoso.com/wickedsecret?ssl=true"
driverClassName="org.postgresql.Driver"
username="postgres"
password="t00secure2gue$$"
/>
En este caso, podría cambiarlo como se muestra en el ejemplo siguiente:
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="${postgresdb.connectionString}"
driverClassName="org.postgresql.Driver"
username="${postgresdb.username}"
password="${postgresdb.password}"
/>
Para garantizar que la sustitución de parámetros se produce para cualquier archivo context.xml dentro de la carpeta META-INF dentro de un archivo .war implementado, asegúrese de establecer la variable de entorno CATALINA_OPTS
, tal como se muestra en el ejemplo siguiente:
export CATALINA_OPTS="-Dorg.apache.tomcat.util.digester.PROPERTY_SOURCE=org.apache.tomcat.util.digester.EnvironmentPropertySource"
Aprovisionamiento de un plan de App Service
En la lista de planes de servicio disponibles en Precios de App Service, seleccione el plan cuyas especificaciones sean igual o superiores a las del hardware de producción actual.
Nota:
Si planea ejecutar implementaciones de ensayo o controladas, o usar espacios de implementación, el plan de App Service debe incluir esa funcionalidad adicional. Se recomienda usar planes Premium o superiores para las aplicaciones de Java. Para más información, consulte Configuración de entornos de ensayo en Azure App Service.
Después, cree un plan de App Service. Para más información, consulte Cambio de una aplicación a otro plan de App Service.
Creación e implementación de aplicaciones web
Tendrá que crear una aplicación web en su plan de App Service (con una versión de Tomcat como pila en tiempo de ejecución) para cada archivo WAR implementado en el servidor de Tomcat.
Nota:
Aunque es posible implementar varios archivos WAR en una sola aplicación web, es muy poco recomendable. La implementación de varios archivos WAR en una sola aplicación web impide que cada aplicación escale según sus propias demandas de uso. También agrega complejidad a las posteriores canalizaciones de implementación. Si tiene que haber varias aplicaciones disponibles en una sola dirección URL, considere la posibilidad de usar una solución de enrutamiento como Azure Application Gateway.
Aplicaciones de Maven
Si la aplicación se ha creado a partir de un archivo POM de Maven, usará el complemento Webapp para Maven para crear la aplicación web e implementarla.
Aplicaciones que no son de Maven
Si no puede usar el complemento de Maven, debe aprovisionar la aplicación web con otros mecanismos, como:
Una vez creada la aplicación web, use uno de los mecanismos de implementación disponibles para implementar la aplicación.
Migración de las opciones de tiempo de ejecución de JVM
Si la aplicación requiere opciones de tiempo de ejecución específicas, use el mecanismo más adecuado para especificarlas.
Relleno de secretos
Use la configuración de la aplicación para almacenar los secretos específicos de la aplicación. Si piensa utilizar los mismos secretos en varias aplicaciones o requiere funcionalidades de auditoría y directivas de acceso específicas, use Azure Key Vault en su lugar.
Configuración del dominio personalizado y SSL
Si la aplicación va a ser visible en un dominio personalizado, tendrá que asignarle su aplicación web. Para más información, consulte Tutorial: Asignación de un nombre DNS personalizado existente a Azure App Service.
Después, tendrá que enlazar el certificado SSL de ese dominio a la aplicación web de App Service. Para más información, consulte Protección de un nombre DNS personalizado con un enlace SSL en Azure App Service.
Importación de certificados de backend
Todos los certificados que se van a comunicar con los sistemas de backend, como las bases de datos, deben estar disponibles para App Service. Para más información, consulte Adición de un certificado SSL en App Service.
Migración de orígenes de datos, bibliotecas y recursos de JNDI
Para conocer los pasos de configuración de los orígenes de datos, consulte la sección Orígenes de datos de Configuración de una aplicación de Java en Linux para Azure App Service.
Para más instrucciones sobre orígenes de datos, consulte las siguientes secciones de los artículos de procedimientos de los orígenes de datos JNDI en la documentación de Tomcat:
Migre las demás dependencias de CLASSPATH en el nivel de servidor siguiendo los mismos pasos que para los archivos JAR de origen de datos.
Migre otros recursos de JDNI adicionales compartidos en el nivel de servidor.
Nota:
Si está siguiendo la arquitectura recomendada de un archivo WAR por aplicación web, considere la posibilidad de migrar las bibliotecas de CLASSPATH en el nivel de servidor y los recursos de JNDI a su aplicación. Esto simplificará considerablemente la administración de cambios y la gobernanza de los componentes.
Migración de la configuración restante
Después de completar la sección anterior, tendrá la configuración de servidor personalizable en /home/tomcat/conf.
Para completar la migración, copie otra configuración adicional (por ejemplo, realms y JASPIC).
Migración de los trabajos programados
Para ejecutar trabajos programados en Azure, considere la posibilidad de usar un desencadenador de temporizador para Azure Functions. No es necesario migrar el propio código de trabajo a una función. La función simplemente puede invocar una dirección URL en la aplicación para desencadenar el trabajo. Si estas ejecuciones de trabajos se deben invocar dinámicamente o hay que hacer un seguimiento centralizado, considere la posibilidad de usar Spring Batch.
También puede crear una aplicación lógica con un desencadenador de periodicidad para invocar la dirección URL sin escribir ningún código fuera de la aplicación. Para más información, consulte Introducción: ¿Qué es Azure Logic Apps? y Creación, programación y ejecución de tareas y flujos de trabajo periódicos con el desencadenador de periodicidad en Azure Logic Apps.
Nota:
Para evitar el uso malintencionado, asegúrese de que el punto de conexión de invocación del trabajo requiera credenciales. En este caso, la función de desencadenador deberá proporcionar las credenciales.
Reinicio y prueba de humo
Por último, tendrá que reiniciar la aplicación web para aplicar todos los cambios de la configuración. Tras completar el reinicio, compruebe que la aplicación se está ejecutando correctamente.
Después de la migración
Ahora que ha migrado la aplicación a Azure App Service, debe comprobar que funciona como se espera. Una vez hecho esto, tenemos algunas recomendaciones que pueden hacer que su aplicación sea más nativa de la nube.
Recomendaciones
Si ha optado por usar el directorio /home para el almacenamiento de archivos, considere la posibilidad de reemplazarlo por Azure Storage.
Si tiene una configuración en el directorio /home que contiene cadenas de conexión, claves SSL y otra información secreta, considere la posibilidad de usar una combinación de Azure Key Vault e inyección de parámetros con la configuración de la aplicación siempre que sea posible.
Considere la posibilidad de usar espacios de implementación para realizar implementaciones confiables sin tiempo de inactividad.
Diseñe e implemente una estrategia de DevOps. Para mantener la confiabilidad y, al mismo tiempo, aumentar la velocidad de desarrollo, considere la posibilidad de automatizar las implementaciones y pruebas con Azure Pipelines. Si usa espacios de implementación, puede automatizar la implementación en un espacio y después cambiar de espacio.
Diseñe e implemente una estrategia de continuidad empresarial y recuperación ante desastres. En el caso de las aplicaciones críticas, considere la posibilidad de usar una arquitectura de implementación de varias regiones.