Configuración de una aplicación Java para Azure App Service

Nota:

Para las aplicaciones de Spring, se recomienda usar Azure Spring Apps. No obstante, todavía puede usar Azure App Service como destino. Consulte guía de destino de carga de trabajo de Java para obtener consejos.

Azure App Service permite a los desarrolladores de Java compilar, implementar y escalar rápidamente sus aplicaciones web de Java SE, Tomcat y JBoss EAP en un servicio totalmente administrado. Implemente aplicaciones con complementos de Maven desde la línea de comandos o en editores, como IntelliJ, Eclipse o Visual Studio Code.

Esta guía incluye conceptos clave e instrucciones para los desarrolladores de Java que usan App Service. Si nunca ha usado Azure App Service, debe leer primero la Guía de inicio rápido de Java. Encontrará respuestas a las preguntas generales sobre el uso de App Service que no son específicas del desarrollo de Java en Preguntas más frecuentes sobre Azure App Service.

Visualización de la versión de Java

Para mostrar la versión actual de Java, ejecute el siguiente comando en Cloud Shell:

az webapp config show --name <app-name> --resource-group <resource-group-name> --query "[javaVersion, javaContainer, javaContainerVersion]"

Para mostrar todas las versiones compatibles de Java, ejecute el siguiente comando en Cloud Shell:

az webapp list-runtimes --os windows | grep java

Para mostrar la versión actual de Java, ejecute el siguiente comando en Cloud Shell:

az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion

Para mostrar todas las versiones compatibles de Java, ejecute el siguiente comando en Cloud Shell:

az webapp list-runtimes --os linux | grep "JAVA\|TOMCAT\|JBOSSEAP"

Para obtener más información sobre la compatibilidad con versiones, consulte Directiva de compatibilidad de runtime de idiomas de App Service.

Implementación de la aplicación

Build Tools

Maven

Con el complemento Maven para Azure Web Apps, puede preparar fácilmente el proyecto de Java de Maven con un comando en la raíz del proyecto:

mvn com.microsoft.azure:azure-webapp-maven-plugin:2.11.0:config

Este comando agrega un complemento azure-webapp-maven-plugin y una configuración relacionada al pedirle que seleccione una aplicación web de Azure existente o que cree una nueva. Luego, puede implementar la aplicación Java en Azure mediante el siguiente comando:

mvn package azure-webapp:deploy

Esta es una configuración de ejemplo de pom.xml:

<plugin> 
  <groupId>com.microsoft.azure</groupId>  
  <artifactId>azure-webapp-maven-plugin</artifactId>  
  <version>2.11.0</version>  
  <configuration>
    <subscriptionId>111111-11111-11111-1111111</subscriptionId>
    <resourceGroup>spring-boot-xxxxxxxxxx-rg</resourceGroup>
    <appName>spring-boot-xxxxxxxxxx</appName>
    <pricingTier>B2</pricingTier>
    <region>westus</region>
    <runtime>
      <os>Linux</os>      
      <webContainer>Java SE</webContainer>
      <javaVersion>Java 11</javaVersion>
    </runtime>
    <deployment>
      <resources>
        <resource>
          <type>jar</type>
          <directory>${project.basedir}/target</directory>
          <includes>
            <include>*.jar</include>
          </includes>
        </resource>
      </resources>
    </deployment>
  </configuration>
</plugin> 

Gradle

  1. Configure el complemento Gradle para Azure Web Apps mediante su incorporación a build.gradle:

    plugins {
      id "com.microsoft.azure.azurewebapp" version "1.7.1"
    }
    
  2. Configure los detalles de la aplicación web. Los recursos de Azure correspondientes se crean si no existen. Esta es una configuración de ejemplo. Para obtener detalles, vea este documento.

    azurewebapp {
        subscription = '<your subscription id>'
        resourceGroup = '<your resource group>'
        appName = '<your app name>'
        pricingTier = '<price tier like 'P1v2'>'
        region = '<region like 'westus'>'
        runtime {
          os = 'Linux'
          webContainer = 'Tomcat 9.0' // or 'Java SE' if you want to run an executable jar
          javaVersion = 'Java 8'
        }
        appSettings {
            <key> = <value>
        }
        auth {
            type = 'azure_cli' // support azure_cli, oauth2, device_code and service_principal
        }
    }
    
  3. Implemente con un comando.

    gradle azureWebAppDeploy
    

IDE

Azure proporciona una experiencia de desarrollo de Java App Service eficiente en los entornos de desarrollo de Java más populares, incluidos:

API de Kudu

Java SE

Para implementar archivos .jar en Java SE, use el punto de conexión /api/publish/ del sitio de Kudu. Para más información sobre esta API, consulte esta documentación.

Nota

La aplicación .jar debe tener el nombre app.jar para App Service y así poder identificar y ejecutar la aplicación. El complemento Maven lo hace automáticamente durante la implementación. Si no quiere cambiar el nombre de archivo JAR a app.jar, puede cargar un script de shell con el comando para ejecutar la aplicación .jar. Pegue la ruta de acceso absoluta a este script en el cuadro de textoArchivo de inicio de la sección Configuración del portal. El script de inicio no se ejecuta desde el directorio en el que se encuentra. Por lo tanto, use siempre rutas de acceso absolutas para hacer referencia a los archivos del script de inicio (por ejemplo: java -jar /home/myapp/myapp.jar).

Tomcat

Para implementar archivos .war en Tomcat, utilice el punto de conexión /api/wardeploy/ para realizar el conjunto de rutinas POST en el archivo. Para más información sobre esta API, consulte esta documentación.

JBoss EAP

Para implementar archivos .war en JBoss, use el punto de conexión /api/wardeploy/ para realizar la instrucción POST en el archivo. Para más información sobre esta API, consulte esta documentación.

Para implementar archivos .ear, use FTP. La aplicación .ear se implementa en la raíz de contexto definida en la configuración de la aplicación. Por ejemplo, si la raíz de contexto de la aplicación es <context-root>myapp</context-root>, puede examinar el sitio en la ruta de acceso /myapp: http://my-app-name.azurewebsites.net/myapp. Si desea que se atienda a la aplicación web en la ruta de acceso raíz, asegúrese de que la aplicación establece la raíz del contexto en la ruta de acceso raíz: <context-root>/</context-root>. Para obtener más información, vea Establecimiento del contexto raíz de una aplicación web.

No implemente el archivo .war o .jar con el FTP. La herramienta FTP está diseñada para cargar los scripts de inicio, dependencias u otros archivos en tiempo de ejecución. Tenga en cuenta que no es la opción óptima para realizar la implementación de aplicaciones web.

Registro y depuración de aplicaciones

Encontrará informes de rendimiento, visualizaciones de tráfico y comprobaciones de mantenimiento de cada aplicación a través de Azure Portal. Para más información, consulte Introducción a los diagnósticos de Azure App Service.

Transmisión de registros de diagnóstico

Para acceder a los registros de la consola generados desde el código de la aplicación en App Service, active el registro de diagnósticos, para lo que debe ejecutar el siguiente comando en Cloud Shell:

az webapp log config --resource-group <resource-group-name> --name <app-name> --docker-container-logging filesystem --level Verbose

Los valores posibles de --level son: Error, Warning, Info y Verbose. Todos los niveles incluyen el nivel anterior. Por ejemplo: Error incluye solo los mensajes de error, mientras que Verbose incluye todos los mensajes.

Una vez que se activa el registro de contenedor, ejecute el siguiente comando para ver la transmisión del registro:

az webapp log tail --resource-group <resource-group-name> --name <app-name>

Si no ve los registros de la consola de inmediato, vuelve a comprobarlo en 30 segundos.

Nota

También puede inspeccionar los archivos de registro desde el explorador en https://<app-name>.scm.azurewebsites.net/api/logs/docker.

Para detener el streaming del registro en cualquier momento, escriba Ctrl+C.

Puede acceder a los registros de consola generados desde dentro del contenedor.

En primer lugar, active el registro de contenedores mediante la ejecución del siguiente comando:

az webapp log config --name <app-name> --resource-group <resource-group-name> --docker-container-logging filesystem

Reemplace <app-name> y <resource-group-name> por los nombres adecuados para su aplicación web.

Una vez que se active el registro de contenedor, ejecute el siguiente comando para ver el flujo del registro:

az webapp log tail --name <app-name> --resource-group <resource-group-name>

Si no ve los registros de la consola de inmediato, vuelve a comprobarlo en 30 segundos.

Para detener el streaming de registro en cualquier momento, escriba Ctrl+C.

Los archivos de registro también se pueden inspeccionar en un explorador en https://<app-name>.scm.azurewebsites.net/api/logs/docker.

Para más información, consulte Registros de secuencias en Cloud Shell.

Acceso a la consola SSH

Para que una sesión de SSH directa sea abierta con el contenedor, la aplicación debe estar en ejecución.

Pegue la siguiente dirección URL en el explorador y reemplace <app-name> por el nombre de la aplicación:

https://<app-name>.scm.azurewebsites.net/webssh/host

Si aún no está autenticado, será preciso que se autentique con su suscripción a Azure para conectarse. Una vez autenticado, verá un shell del explorador en el que puede ejecutar comandos dentro del contenedor.

Conexión SSH

Nota

Los cambios que realice fuera del directorio /home se almacenan en el propio contenedor y no se conservan después del primer reinicio de la aplicación.

Para abrir una sesión remota de SSH desde un equipo local, consulte Abrir sesión SSH desde un shell remoto.

Herramienta para la solución de problemas

Las imágenes de Java integradas usan el sistema operativo Alpine Linux. Use el administrador de paquetes apk para instalar todas las herramientas o comandos para la solución de problemas.

Java Profiler

Todos los entornos de ejecución de Java en Azure App Service vienen con JDK Flight Recorder para la generación de perfiles de cargas de trabajo de Java. Puede usarla para grabar eventos de JVM, de aplicación y del sistema, así como para solucionar los problemas de las aplicaciones.

Para más información sobre Java Profiler, visite la documentación de Azure Application Insights.

Caja negra SQL

Todos los entornos de ejecución de Java en App Service incluyen Java Flight Recorder. Puede usarlo para grabar eventos JVM, de aplicación y del sistema, así como para solucionar los problemas de las aplicaciones Java.

Grabación temporizada

Para realizar una grabación temporizada, necesita el PID (id. de proceso) de la aplicación Java. Para buscar el PID, abra un explorador en el sitio de SCM de la aplicación web en https://<your-site-name>.scm.azurewebsites.net/ProcessExplorer/. En esta página se muestran los procesos en ejecución en la aplicación web. Busque el proceso denominado "Java" en la tabla y copie el PID (identificador de proceso) correspondiente.

A continuación, abra la Consola de depuración en la barra de herramientas superior del sitio de SCM y ejecute el siguiente comando. Reemplace <pid> por el identificador de proceso que ha copiado anteriormente. Este comando inicia una grabación de 30 segundos del generador de perfiles de su aplicación Java y genera un archivo denominado timed_recording_example.jfr en el directorio C:\home.

jcmd <pid> JFR.start name=TimedRecording settings=profile duration=30s filename="C:\home\timed_recording_example.JFR"

Conéctese a App Service mediante SSH y ejecute el comando jcmd para ver una lista de todos los procesos de Java en ejecución. Además del propio jcmd, debería ver la aplicación de Java que se ejecuta con un número de Id. de proceso (pid).

078990bbcd11:/home# jcmd
Picked up JAVA_TOOL_OPTIONS: -Djava.net.preferIPv4Stack=true
147 sun.tools.jcmd.JCmd
116 /home/site/wwwroot/app.jar

Ejecute el siguiente comando para iniciar una grabación de 30 segundos de la JVM. Así se generará el perfil de JVM y se creará un archivo JFR denominado jfr_example.jfr en el directorio principal. (reemplace 116 por el pid de la aplicación de Java).

jcmd 116 JFR.start name=MyRecording settings=profile duration=30s filename="/home/jfr_example.jfr"

Durante el intervalo de 30 segundos puede validar que la grabación se lleva a cabo mediante la ejecución de jcmd 116 JFR.check. Esto mostrará todas las grabaciones del proceso de Java dado.

Grabación continua

Puede usar Zulu Flight Recorder para generar perfiles continuamente de una aplicación Java con un impacto mínimo en el rendimiento del entorno de ejecución. Para ello, ejecute el siguiente comando de la CLI de Azure para crear una configuración de aplicación denominada JAVA_OPTS con la configuración necesaria. El contenido de la configuración de la aplicación de JAVA_OPTS se pasa al comando java cuando se inicia la aplicación.

az webapp config appsettings set -g <your_resource_group> -n <your_app_name> --settings JAVA_OPTS=-XX:StartFlightRecording=disk=true,name=continuous_recording,dumponexit=true,maxsize=1024m,maxage=1d

Cuando se inicie la grabación, puede volcar los datos de grabación actuales en cualquier momento mediante el comando JFR.dump.

jcmd <pid> JFR.dump name=continuous_recording filename="/home/recording1.jfr"

Análisis de archivos .jfr

Use FTPS para descargar el archivo JFR en el equipo local. Para analizar el archivo JFR, descargue e instale Java Mission Control. Para obtener instrucciones sobre Java Mission Control, consulte la documentación de JMC y las instrucciones de instalación.

Registro de aplicaciones

Habilite el registro de aplicaciones a través de Azure Portal o la CLI de Azure para configurar App Service para que escriba los flujos de salida y de error de la consola estándar en el sistema de archivos local o en Azure Blob Storage. El registro en el sistema de archivos local de App Service se deshabilita 12 horas después de su configuración. Si necesita una retención más prolongada, configure la aplicación para escribir la salida en un contenedor de Blob Storage. Los registros de aplicación de Java y Tomcat pueden encontrarse en el directorio /home/LogFiles/Application/ .

Habilite el registro de aplicaciones a través de Azure Portal o la CLI de Azure para configurar App Service para que escriba los flujos de salida y de error de la consola estándar en el sistema de archivos local o en Azure Blob Storage. Si necesita una retención más prolongada, configure la aplicación para escribir la salida en un contenedor de Blob Storage. Los registros de aplicación de Java y Tomcat pueden encontrarse en el directorio /home/LogFiles/Application/ .

El registro de Azure Blob Storage para aplicaciones basadas en Linux solo se puede configurar mediante Azure Monitor.

Si la aplicación usa Logback o Log4j para el seguimiento, puede reenviar estos seguimientos para su revisión en Azure Application Insights mediante las instrucciones de configuración del marco de registro en Exploración de los registros de seguimiento de Java en Application Insights.

Nota

Debido a la vulnerabilidad conocida CVE-2021-44228, asegúrese de usar la versión 2.16 o posterior de Log4j.

Personalización y optimización

Azure App Service admite la optimización y la personalización de serie a través de Azure Portal y de la CLI de Azure. Consulte los artículos siguientes para conocer la configuración de aplicaciones web específicas que no son de Java:

Copia local del contenido de la aplicación

Establezca la configuración JAVA_COPY_ALL de la aplicación en true para copiar el contenido de la aplicación en el trabajo local desde el sistema de archivos compartido. Esta configuración ayuda a solucionar problemas de bloqueo de archivos.

Definición de las opciones de Java Runtime

Para establecer la memoria asignada u otras opciones de runtime de JVM, cree una configuración de la aplicación denominada JAVA_OPTS con las opciones. App Service pasa esta configuración como variable de entorno para Java Runtime cuando se inicia.

En Azure Portal, en Configuración de la aplicación para la aplicación web, cree un valor de la aplicación denominado JAVA_OPTS para Java SE o CATALINA_OPTS para Tomcat que incluya otros valores de configuración, como -Xms512m -Xmx1204m.

Para definir la configuración de la aplicación desde el complemento MavenLinux, agregue las etiquetas setting/value a la sección de complementos de Azure. En el ejemplo siguiente se establece un tamaño del montón de Java mínimo y máximo específico:

<appSettings>
    <property>
        <name>JAVA_OPTS</name>
        <value>-Xms1024m -Xmx1024m</value>
    </property>
</appSettings>

Nota:

No es necesario crear un archivo web.config al usar Tomcat en Windows App Service.

Los desarrolladores que ejecutan una sola aplicación con una ranura de implementación en su plan de App Service pueden usar las siguientes opciones:

  • Instancias de S1 y B1: -Xms1024m -Xmx1024m
  • Instancias de S2 y B2: -Xms3072m -Xmx3072m
  • Instancias de S3 y B3: -Xms6144m -Xmx6144m
  • Instancias de P1v2: -Xms3072m -Xmx3072m
  • Instancias de P2v2: -Xms6144m -Xmx6144m
  • Instancias de P3v2: -Xms12800m -Xmx12800m
  • Instancias de P1v3: -Xms6656m -Xmx6656m
  • Instancias de P2v3: -Xms14848m -Xmx14848m
  • Instancias de P3v3: -Xms30720m -Xmx30720m
  • Instancias de I1: -Xms3072m -Xmx3072m
  • Instancias de I2: -Xms6144m -Xmx6144m
  • Instancias de I3: -Xms12800m -Xmx12800m
  • Instancias de I1v2: -Xms6656m -Xmx6656m
  • Instancias de I2v2: -Xms14848m -Xmx14848m
  • Instancias de I3v2: -Xms30720m -Xmx30720m

Cuando optimice la configuración del montón de la aplicación, revise los detalles de su plan de App Service y tenga en cuenta distintas necesidades de aplicaciones y ranuras de implementación para encontrar la asignación óptima de memoria.

Activación de sockets web

Active la compatibilidad con sockets web en Azure Portal en Configuración de la aplicación para la aplicación. Debe reiniciar la aplicación para que la configuración surta efecto.

Active la compatibilidad con los sockets web mediante la CLI de Azure con el comando siguiente:

az webapp config set --name <app-name> --resource-group <resource-group-name> --web-sockets-enabled true

A continuación, reinicie su aplicación:

az webapp stop --name <app-name> --resource-group <resource-group-name>
az webapp start --name <app-name> --resource-group <resource-group-name>

Definición de la codificación de caracteres predeterminada

En Azure Portal, en Configuración de la aplicación para la aplicación web, cree un nuevo valor de la aplicación denominado JAVA_OPTS con el valor -Dfile.encoding=UTF-8.

También puede configurar el valor de la aplicación mediante el complemento de Maven de App Service. Agregue las etiquetas setting y value del valor en la configuración del complemento:

<appSettings>
    <property>
        <name>JAVA_OPTS</name>
        <value>-Dfile.encoding=UTF-8</value>
    </property>
</appSettings>

Precompilación de archivos JSP

Para mejorar el rendimiento de las aplicaciones Tomcat, puede compilar los archivos JSP antes de realizar la implementación en App Service. Puede usar el complemento Maven proporcionado por Apache Sling o este archivo de compilación Ant.

Aplicaciones seguras

Las aplicaciones de Java que se ejecutan en App Service presentan el mismo conjunto de procedimientos recomendados de seguridad que otras aplicaciones.

Autenticación de usuarios (autenticación sencilla)

Configure la autenticación de la aplicación en Azure Portal con la opción Autenticación y autorización. Desde allí, puede habilitar la autenticación con Microsoft Entra ID o con inicios de sesión en redes sociales como Facebook, Google o GitHub. La configuración de Azure Portal solo funciona al configurar un proveedor de autenticación único. Para más información, consulte Configuración de una aplicación de App Service para usar el inicio de sesión de Microsoft Entra y los artículos relacionados de otros proveedores de identidades. Si tiene que habilitar varios proveedores de inicio de sesión, siga las instrucciones de Personalización del inicio y cierre de sesión.

Java SE

Los desarrolladores de Spring Boot pueden usar el iniciador de Spring Boot para Microsoft Entra para proteger las aplicaciones mediante las anotaciones y las API conocidas de Spring Security. Asegúrese de aumentar el tamaño máximo del encabezado en el archivo application.properties. Se recomienda un valor de 16384.

Tomcat

La aplicación Tomcat puede acceder a las reclamaciones del usuario directamente desde el servlet mediante la conversión del objeto Principal a un objeto Map. El objeto Map asigna cada tipo de notificación a una colección de las notificaciones de dicho tipo. En el ejemplo de código siguiente, request es una instancia de HttpServletRequest.

Map<String, Collection<String>> map = (Map<String, Collection<String>>) request.getUserPrincipal();

Ahora puede inspeccionar el objeto Map de cualquier notificación específica. Por ejemplo, el fragmento de código siguiente recorre en iteración todos los tipos de notificación e imprime el contenido de cada colección.

for (Object key : map.keySet()) {
        Object value = map.get(key);
        if (value != null && value instanceof Collection {
            Collection claims = (Collection) value;
            for (Object claim : claims) {
                System.out.println(claims);
            }
        }
    }

Para cerrar la sesión de los usuarios, utilice la ruta de acceso /.auth/ext/logout. Para realizar otras acciones, consulte la documentación sobre la personalización de inicios y cierres de sesión. También hay documentación oficial acerca de la interfaz HttpServletRequest y sus métodos. Los siguientes métodos de servlet también se hidrata métodos según la configuración de App Service:

public boolean isSecure()
public String getRemoteAddr()
public String getRemoteHost()
public String getScheme()
public int getServerPort()

Para deshabilitar esta característica, cree una configuración de aplicación denominada WEBSITE_AUTH_SKIP_PRINCIPAL con un valor de 1. Para deshabilitar todos los filtros de servlet que ha agregado App Service, cree una configuración denominada WEBSITE_SKIP_FILTERS con un valor de 1.

Configuración de TLS/SSL

Para cargar un certificado TLS/SSL existente y enlazarlo al nombre de dominio de la aplicación, siga las instrucciones de Protección de un nombre DNS personalizado con un enlace TLS/SSL en Azure App Service. También puede configurar la aplicación para aplicar TLS/SSL.

Uso de referencias de KeyVault

Azure KeyVault proporciona administración de secretos centralizada con directivas de acceso un historial de directivas. En KeyVault puede almacenar secretos (como contraseñas o cadenas de conexión) y acceder a ellos en la aplicación través de las variables de entorno.

En primer lugar, siga las instrucciones para conceder a su aplicación acceso a un almacén de claves y hacer una referencia de KeyVault a su secreto en una configuración de aplicación. Para validar que la referencia se resuelve en el secreto, imprima la variable de entorno mie3ntras acceder de forma remota al terminal de App Service.

Para insertar estos secretos en el archivo de configuración de Spring o Tomcat, use la sintaxis de inserción de variables de entorno (${MY_ENV_VAR}). En el caso de los archivos de configuración de Spring, consulte esta documentación acerca de las configuraciones externalizadas.

Uso del almacén de claves de Java

De forma predeterminada, los certificados públicos o privados cargados en App Service Linux se cargan en los almacenes de claves de Java respectivos cuando se inicia el contenedor. Después de cargar el certificado, deberá reiniciar la instancia de App Service para que se cargue en el almacén de claves de Java. Los certificados públicos se cargan en el almacén de claves en $JRE_HOME/lib/security/cacerts, y los certificados privados se almacenan en $JRE_HOME/lib/security/client.jks.

Puede ser necesaria más configuración para el cifrado de la conexión de JDBC con certificados en el almacén de claves de Java. Consulte la documentación del controlador JDBC elegido.

Inicialización del almacén de claves de Java

Para inicializar el objeto import java.security.KeyStore, cargue el archivo de almacén de claves con la contraseña. La contraseña predeterminada para ambos almacenes de claves es changeit.

KeyStore keyStore = KeyStore.getInstance("jks");
keyStore.load(
    new FileInputStream(System.getenv("JRE_HOME")+"/lib/security/cacerts"),
    "changeit".toCharArray());

KeyStore keyStore = KeyStore.getInstance("pkcs12");
keyStore.load(
    new FileInputStream(System.getenv("JRE_HOME")+"/lib/security/client.jks"),
    "changeit".toCharArray());

Cargar manualmente el almacén de claves

Puede cargar los certificados manualmente en el almacén de claves. Cree una configuración de aplicación, SKIP_JAVA_KEYSTORE_LOAD, con un valor de 1 para deshabilitar en App Service la carga automática de los certificados en el almacén de claves. Todos los certificados públicos cargados en App Service a través de Azure Portal se almacenan en /var/ssl/certs/. Los certificados privados se almacenan en /var/ssl/private/.

Puede depurar o interactuar con la herramienta de claves de Java si abre una conexión SSH a la instancia de App Service y ejecuta el comando keytool. Consulte la documentación de la herramienta de claves para obtener una lista de comandos. Para más información sobre la API KeyStore, consulte la documentación oficial.

Configuración de plataformas APM

En esta sección se muestra cómo conectar aplicaciones de Java implementadas en Azure App Service con las plataformas de supervisión de rendimiento de aplicaciones (APM) Azure Monitor Application Insights, NewRelic y AppDynamics.

Configuración de Application Insights

Azure Monitor Application Insights es un servicio de supervisión de aplicaciones nativo de la nube que permite a los clientes observar errores, cuellos de botella y patrones de uso para mejorar el rendimiento de la aplicación y reducir el tiempo medio de resolución (MTTR). Con unos pocos clics o comandos de la CLI, puede habilitar la supervisión de las aplicaciones Node.js o Java y recopilar automáticamente registros, métricas y seguimientos distribuidos, lo que elimina la necesidad de incluir un SDK en la aplicación. Para obtener más información sobre la configuración de la aplicación disponible para configurar el agente, consulte la documentación de Application Insights.

Azure portal

Para habilitar Application Insights desde Azure Portal, vaya a Application Insights en el menú de la izquierda y seleccione Activar Application Insights. De forma predeterminada, se usa un nuevo recurso de Application Insights con el mismo nombre que la aplicación web. Puede optar por usar un recurso de Application Insights existente o cambiar el nombre. Seleccione Aplicar en la parte inferior.

CLI de Azure

Para habilitarlo a través de la CLI de Azure, debe crear un recurso de Application Insights y establecer un par de configuraciones de aplicación en Azure Portal para conectar Application Insights a la aplicación web.

  1. Habilitación de la extensión de Applications Insights

    az extension add -n application-insights
    
  2. Cree un recurso de Application Insights mediante el siguiente comando de la CLI. Reemplace los marcadores de posición por el nombre de recurso y el grupo deseados.

    az monitor app-insights component create --app <resource-name> -g <resource-group> --location westus2  --kind web --application-type web
    

    Anote los valores de connectionString y instrumentationKey, los necesitará en el siguiente paso.

    Para recuperar una lista de otras ubicaciones, ejecute az account list-locations.

  1. Establezca la clave de instrumentación, la cadena de conexión y la versión del agente de supervisión como configuración de la aplicación en la aplicación web. Sustituya <instrumentationKey> y <connectionString> por los valores del paso anterior.

    az webapp config appsettings set -n <webapp-name> -g <resource-group> --settings "APPINSIGHTS_INSTRUMENTATIONKEY=<instrumentationKey>" "APPLICATIONINSIGHTS_CONNECTION_STRING=<connectionString>" "ApplicationInsightsAgent_EXTENSION_VERSION=~3" "XDT_MicrosoftApplicationInsights_Mode=default" "XDT_MicrosoftApplicationInsights_Java=1"
    
  1. Establezca la clave de instrumentación, la cadena de conexión y la versión del agente de supervisión como configuración de la aplicación en la aplicación web. Sustituya <instrumentationKey> y <connectionString> por los valores del paso anterior.

    az webapp config appsettings set -n <webapp-name> -g <resource-group> --settings "APPINSIGHTS_INSTRUMENTATIONKEY=<instrumentationKey>" "APPLICATIONINSIGHTS_CONNECTION_STRING=<connectionString>" "ApplicationInsightsAgent_EXTENSION_VERSION=~3" "XDT_MicrosoftApplicationInsights_Mode=default"
    

Configuración de New Relic

  1. Cree una cuenta de NewRelic en NewRelic.com.

  2. Descargue el agente de Java de NewRelic. Tiene un nombre de archivo similar a newrelic-java-x.x.x.zip.

  3. Copie la clave de licencia, ya que la necesitará más tarde para configurar el agente.

  4. Conéctese mediante SSH a su instancia de App Service y cree un nuevo directorio /home/site/wwwroot/apm.

  5. Cargue los archivos desempaquetados del agente de Java de NewRelic en un directorio de /home/site/wwwroot/apm. Los archivos del agente deben estar en /home/site/wwwroot/apm/newrelic.

  6. Modifique el archivo YAML en /home/site/wwwroot/apm/newrelic/newrelic.yml y reemplace el marcador de posición de valor de la licencia por su propia clave de licencia.

  7. En Azure Portal, vaya a la aplicación en App Service y cree una nueva configuración de la aplicación.

    • Para las aplicaciones de Java SE, cree una variable de entorno llamada JAVA_OPTS con el valor -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar.
    • Para las aplicaciones de Tomcat, cree una variable de entorno llamada CATALINA_OPTS con el valor -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar.
  1. Cree una cuenta de NewRelic en NewRelic.com.

  2. Descargue el agente de Java de NewRelic. Tiene un nombre de archivo similar a newrelic-java-x.x.x.zip.

  3. Copie la clave de licencia, ya que la necesitará más tarde para configurar el agente.

  4. Conéctese mediante SSH a su instancia de App Service y cree un nuevo directorio /home/site/wwwroot/apm.

  5. Cargue los archivos desempaquetados del agente de Java de NewRelic en un directorio de /home/site/wwwroot/apm. Los archivos del agente deben estar en /home/site/wwwroot/apm/newrelic.

  6. Modifique el archivo YAML en /home/site/wwwroot/apm/newrelic/newrelic.yml y reemplace el marcador de posición de valor de la licencia por su propia clave de licencia.

  7. En Azure Portal, vaya a la aplicación en App Service y cree una nueva configuración de la aplicación.

    • Para las aplicaciones de Java SE, cree una variable de entorno llamada JAVA_OPTS con el valor -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar.
    • Para las aplicaciones de Tomcat, cree una variable de entorno llamada CATALINA_OPTS con el valor -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar.

Si ya tiene una variable de entorno para JAVA_OPTS o CATALINA_OPTS, anexe la opción -javaagent:/... al final del valor actual.

Configuración de AppDynamics

  1. Cree una cuenta de AppDynamics en AppDynamics.com.

  2. Descargue el agente de Java desde el sitio web de AppDynamics. El nombre de archivo es similar a AppServerAgent-x.x.x.xxxxx.zip

  3. Use la consola de Kudu para crear un directorio /home/site/wwwroot/apm.

  4. Cargue los archivos del agente de Java en un directorio de /home/site/wwwroot/apm. Los archivos del agente deben estar en /home/site/wwwroot/apm/appdynamics.

  5. En Azure Portal, vaya a la aplicación en App Service y cree una nueva configuración de la aplicación.

    • Para las aplicaciones de Java SE, cree una variable de entorno llamada JAVA_OPTS con el valor -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name>, donde <app-name> es el nombre de su instancia de App Service.
    • Para las aplicaciones de Tomcat, cree una variable de entorno llamada CATALINA_OPTS con el valor -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name>, donde <app-name> es el nombre de su instancia de App Service.
  1. Cree una cuenta de AppDynamics en AppDynamics.com.

  2. Descargue el agente de Java desde el sitio web de AppDynamics. El nombre de archivo es similar a AppServerAgent-x.x.x.xxxxx.zip

  3. Conéctese mediante SSH a su instancia de App Service y cree un nuevo directorio /home/site/wwwroot/apm.

  4. Cargue los archivos del agente de Java en un directorio de /home/site/wwwroot/apm. Los archivos del agente deben estar en /home/site/wwwroot/apm/appdynamics.

  5. En Azure Portal, vaya a la aplicación en App Service y cree una nueva configuración de la aplicación.

    • Para las aplicaciones de Java SE, cree una variable de entorno llamada JAVA_OPTS con el valor -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name>, donde <app-name> es el nombre de su instancia de App Service.
    • Para las aplicaciones de Tomcat, cree una variable de entorno llamada CATALINA_OPTS con el valor -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name>, donde <app-name> es el nombre de su instancia de App Service.

Nota

Si ya tiene una variable de entorno para JAVA_OPTS o CATALINA_OPTS, anexe la opción -javaagent:/... al final del valor actual.

Configuración de orígenes de datos

Java SE

Para conectarse a orígenes de datos en aplicaciones de Spring Boot, se recomienda crear cadenas de conexión e insertarlas en su archivo application.properties.

  1. En la sección "Configuración" de la página de App Service, establezca un nombre para la cadena, pegue la cadena de conexión de JDBC en el campo de valor y establezca el tipo en "Custom" (Personalizado). Opcionalmente, puede establecer esta cadena de conexión como configuración de ranura.

    Nuestra aplicación puede acceder a cadena de conexión como una variable de entorno denominada CUSTOMCONNSTR_<your-string-name>. Por ejemplo, CUSTOMCONNSTR_exampledb.

  2. En su archivo application.properties, haga referencia a esta cadena de conexión con el nombre de variable de entorno. En nuestro ejemplo, se usaría lo siguiente.

    app.datasource.url=${CUSTOMCONNSTR_exampledb}
    

Para obtener más información, consulte la documentación de Spring Boot relativa al acceso a datos y configuraciones externalizadas .

Tomcat

Estas instrucciones se aplican a todas las conexiones de base de datos. Debe rellenar los marcadores de posición con el nombre de clase de controlador de la base de datos elegido y con el archivo JAR. Se proporciona una tabla con los nombres de clase y las descargas de controladores de las bases de datos más habituales.

Base de datos Nombre de clase de controlador Controlador JDBC
PostgreSQL org.postgresql.Driver Descargar
MySQL com.mysql.jdbc.Driver Descargar (seleccione "Platform Independent")
SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver Descargar

Para configurar Tomcat para que use Java Database Connectivity (JDBC) o Java Persistence API (JPA), personalice primero la variable de entorno CATALINA_OPTS que lee Tomcat al iniciarse. Establezca estos valores a través de un valor de la aplicación en el complemento de Maven de App Service:

<appSettings>
    <property>
        <name>CATALINA_OPTS</name>
        <value>"$CATALINA_OPTS -Ddbuser=${DBUSER} -Ddbpassword=${DBPASSWORD} -DconnURL=${CONNURL}"</value>
    </property>
</appSettings>

O bien establezca las variables de entorno en la página Configuración>Configuración de la aplicación de Azure Portal.

A continuación, determine si el origen de datos debe estar disponible para una aplicación o para todas las aplicaciones que se ejecutan en el servlet de Tomcat.

Orígenes de datos de nivel de aplicación

  1. Cree un archivo context.xml en el directorio META-INF / del proyecto. Si el directorio META-INF/ no existe, créelo.

  2. En , context.xml, agregue un elemento Context para vincular el origen de datos a una dirección JNDI. Reemplace el marcador de posición driverClassName por el nombre de clase de su controlador de la tabla anterior.

    <Context>
        <Resource
            name="jdbc/dbconnection"
            type="javax.sql.DataSource"
            url="${connURL}"
            driverClassName="<insert your driver class name>"
            username="${dbuser}"
            password="${dbpassword}"
        />
    </Context>
    
  3. Actualice el archivo web.xml de la aplicación para que use el origen de datos de su aplicación.

    <resource-env-ref>
        <resource-env-ref-name>jdbc/dbconnection</resource-env-ref-name>
        <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
    </resource-env-ref>
    

Recursos de nivel de servidor compartidos

Las instalaciones de Tomcat en App Service en Windows existen en el espacio compartido del plan de App Service. No se puede modificar directamente una instalación de Tomcat para la configuración de todo el servidor. Para realizar modificaciones en la configuración de nivel de servidor en la instalación de Tomcat, debe copiar Tomcat en una carpeta local, en la que podrá modificar dicha configuración.

Automatización de la creación de una instancia personalizada de Tomcat al iniciar la aplicación

Puede usar un script de inicio para realizar acciones antes de que se inicie una aplicación web. El script de inicio para personalizar Tomcat debe completar los siguientes pasos:

  1. Compruebe si Tomcat ya se ha copiado y configurado localmente. De ser así, el script de inicio puede terminar aquí.
  2. Copie Tomcat localmente.
  3. Realice los cambios de configuración necesarios.
  4. Indique que la configuración se completó correctamente.

Para aplicaciones de Windows, cree un archivo denominado startup.cmd o startup.ps1 en el directorio wwwroot. Se ejecutará automáticamente antes de que se inicie el servidor de Tomcat.

Este es un script de PowerShell que completa estos pasos:

    # Check for marker file indicating that config has already been done
    if(Test-Path "$Env:LOCAL_EXPANDED\tomcat\config_done_marker"){
        return 0
    }

    # Delete previous Tomcat directory if it exists
    # In case previous config isn't completed or a new config should be forcefully installed
    if(Test-Path "$Env:LOCAL_EXPANDED\tomcat"){
        Remove-Item "$Env:LOCAL_EXPANDED\tomcat" --recurse
    }

    # Copy Tomcat to local
    # Using the environment variable $AZURE_TOMCAT90_HOME uses the 'default' version of Tomcat
    Copy-Item -Path "$Env:AZURE_TOMCAT90_HOME\*" -Destination "$Env:LOCAL_EXPANDED\tomcat" -Recurse

    # Perform the required customization of Tomcat
    {... customization ...}

    # Mark that the operation was a success
    New-Item -Path "$Env:LOCAL_EXPANDED\tomcat\config_done_marker" -ItemType File
Transformaciones

Un caso de uso común para personalizar una versión de Tomcat consiste en modificar los archivos de configuración de Tomcat server.xml, context.xml o web.xml. App Service ya modifica estos archivos para proporcionar características de la plataforma. Para seguir usando estas características, es importante conservar el contenido de estos archivos al realizar cambios en ellos. Para ello, se recomienda usar una transformación XSL (XSLT). Use una transformación XSL para realizar cambios en los archivos XML a la vez que se conserva el contenido original del archivo.

Archivo XSLT de ejemplo

Esta transformación de ejemplo agrega un nuevo nodo de conector a server.xml. Observe la Transformación de identidad, que conserva el contenido original del archivo.

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <!-- Identity transform: this ensures that the original contents of the file are included in the new file -->
    <!-- Ensure that your transform files include this block -->
    <xsl:template match="@* | node()" name="Copy">
      <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="@* | node()" mode="insertConnector">
      <xsl:call-template name="Copy" />
    </xsl:template>

    <xsl:template match="comment()[not(../Connector[@scheme = 'https']) and
                                   contains(., '&lt;Connector') and
                                   (contains(., 'scheme=&quot;https&quot;') or
                                    contains(., &quot;scheme='https'&quot;))]">
      <xsl:value-of select="." disable-output-escaping="yes" />
    </xsl:template>

    <xsl:template match="Service[not(Connector[@scheme = 'https'] or
                                     comment()[contains(., '&lt;Connector') and
                                               (contains(., 'scheme=&quot;https&quot;') or
                                                contains(., &quot;scheme='https'&quot;))]
                                    )]
                        ">
      <xsl:copy>
        <xsl:apply-templates select="@* | node()" mode="insertConnector" />
      </xsl:copy>
    </xsl:template>

    <!-- Add the new connector after the last existing Connnector if there's one -->
    <xsl:template match="Connector[last()]" mode="insertConnector">
      <xsl:call-template name="Copy" />

      <xsl:call-template name="AddConnector" />
    </xsl:template>

    <!-- ... or before the first Engine if there's no existing Connector -->
    <xsl:template match="Engine[1][not(preceding-sibling::Connector)]"
                  mode="insertConnector">
      <xsl:call-template name="AddConnector" />

      <xsl:call-template name="Copy" />
    </xsl:template>

    <xsl:template name="AddConnector">
      <!-- Add new line -->
      <xsl:text>&#xa;</xsl:text>
      <!-- This is the new connector -->
      <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" 
                 maxThreads="150" scheme="https" secure="true" 
                 keystoreFile="${{user.home}}/.keystore" keystorePass="changeit"
                 clientAuth="false" sslProtocol="TLS" />
    </xsl:template>

    </xsl:stylesheet>
Función para la transformación XSL

PowerShell tiene herramientas integradas para transformar archivos XML mediante transformaciones XSL. El siguiente script es una función de ejemplo que puede usar en startup.ps1 para realizar la transformación:

    function TransformXML{
        param ($xml, $xsl, $output)

        if (-not $xml -or -not $xsl -or -not $output)
        {
            return 0
        }

        Try
        {
            $xslt_settings = New-Object System.Xml.Xsl.XsltSettings;
            $XmlUrlResolver = New-Object System.Xml.XmlUrlResolver;
            $xslt_settings.EnableScript = 1;

            $xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
            $xslt.Load($xsl,$xslt_settings,$XmlUrlResolver);
            $xslt.Transform($xml, $output);

        }

        Catch
        {
            $ErrorMessage = $_.Exception.Message
            $FailedItem = $_.Exception.ItemName
            Write-Host  'Error'$ErrorMessage':'$FailedItem':' $_.Exception;
            return 0
        }
        return 1
    }
Configuración de la aplicación

La plataforma también debe saber dónde está instalada la versión personalizada de Tomcat. Puede establecer la ubicación de la instalación en el valor de configuración CATALINA_BASE de la aplicación.

Puede usar la CLI de Azure para cambiar este valor:

    az webapp config appsettings set -g $MyResourceGroup -n $MyUniqueApp --settings CATALINA_BASE="%LOCAL_EXPANDED%\tomcat"

O bien, puede cambiar manualmente la configuración en Azure Portal:

  1. Vaya a Configuración>Configuración>Configuración de la aplicación.
  2. Seleccione Nueva configuración de la aplicación.
  3. Use estos valores para crear la configuración:
    1. Nombre: CATALINA_BASE
    2. Valor: "%LOCAL_EXPANDED%\tomcat"
Ejemplo de startup.ps1

El siguiente script de ejemplo copia una instancia de Tomcat personalizada en una carpeta local, realiza una transformación XSL e indica que la transformación se ha realizado correctamente:

    # Locations of xml and xsl files
    $target_xml="$Env:LOCAL_EXPANDED\tomcat\conf\server.xml"
    $target_xsl="$Env:HOME\site\server.xsl"

    # Define the transform function
    # Useful if transforming multiple files
    function TransformXML{
        param ($xml, $xsl, $output)

        if (-not $xml -or -not $xsl -or -not $output)
        {
            return 0
        }

        Try
        {
            $xslt_settings = New-Object System.Xml.Xsl.XsltSettings;
            $XmlUrlResolver = New-Object System.Xml.XmlUrlResolver;
            $xslt_settings.EnableScript = 1;

            $xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
            $xslt.Load($xsl,$xslt_settings,$XmlUrlResolver);
            $xslt.Transform($xml, $output);
        }

        Catch
        {
            $ErrorMessage = $_.Exception.Message
            $FailedItem = $_.Exception.ItemName
            echo  'Error'$ErrorMessage':'$FailedItem':' $_.Exception;
            return 0
        }
        return 1
    }

    $success = TransformXML -xml $target_xml -xsl $target_xsl -output $target_xml

    # Check for marker file indicating that config has already been done
    if(Test-Path "$Env:LOCAL_EXPANDED\tomcat\config_done_marker"){
        return 0
    }

    # Delete previous Tomcat directory if it exists
    # In case previous config isn't completed or a new config should be forcefully installed
    if(Test-Path "$Env:LOCAL_EXPANDED\tomcat"){
        Remove-Item "$Env:LOCAL_EXPANDED\tomcat" --recurse
    }

    md -Path "$Env:LOCAL_EXPANDED\tomcat"

    # Copy Tomcat to local
    # Using the environment variable $AZURE_TOMCAT90_HOME uses the 'default' version of Tomcat
    Copy-Item -Path "$Env:AZURE_TOMCAT90_HOME\*" "$Env:LOCAL_EXPANDED\tomcat" -Recurse

    # Perform the required customization of Tomcat
    $success = TransformXML -xml $target_xml -xsl $target_xsl -output $target_xml

    # Mark that the operation was a success if successful
    if($success){
        New-Item -Path "$Env:LOCAL_EXPANDED\tomcat\config_done_marker" -ItemType File
    }

Finalización de la configuración

Por último, coloque los archivos JAR del controlador en la classpath de Tomcat y reinicie App Service. Asegúrese de que los archivos del controlador JDBC estén disponibles para el cargador de clases de Tomcat. Para ello, colóquelos en el directorio /home/site/lib. En Cloud Shell, ejecute az webapp deploy --type=lib para cada archivo JAR del controlador:

az webapp deploy --resource-group <group-name> --name <app-name> --src-path <jar-name>.jar --type=lib --target-path <jar-name>.jar

Tomcat

Estas instrucciones se aplican a todas las conexiones de base de datos. Debe rellenar los marcadores de posición con el nombre de clase de controlador de la base de datos elegido y con el archivo JAR. Se proporciona una tabla con los nombres de clase y las descargas de controladores de las bases de datos más habituales.

Base de datos Nombre de clase de controlador Controlador JDBC
PostgreSQL org.postgresql.Driver Descargar
MySQL com.mysql.jdbc.Driver Descargar (seleccione "Platform Independent")
SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver Descargar

Para configurar Tomcat para que use Java Database Connectivity (JDBC) o Java Persistence API (JPA), personalice primero la variable de entorno CATALINA_OPTS que lee Tomcat al iniciarse. Establezca estos valores a través de un valor de la aplicación en el complemento de Maven de App Service:

<appSettings>
    <property>
        <name>CATALINA_OPTS</name>
        <value>"$CATALINA_OPTS -Ddbuser=${DBUSER} -Ddbpassword=${DBPASSWORD} -DconnURL=${CONNURL}"</value>
    </property>
</appSettings>

O bien establezca las variables de entorno en la página Configuración>Configuración de la aplicación de Azure Portal.

A continuación, determine si el origen de datos debe estar disponible para una aplicación o para todas las aplicaciones que se ejecutan en el servlet de Tomcat.

Orígenes de datos de nivel de aplicación

  1. Cree un archivo context.xml en el directorio META-INF / del proyecto. Si el directorio META-INF/ no existe, créelo.

  2. En , context.xml, agregue un elemento Context para vincular el origen de datos a una dirección JNDI. Reemplace el marcador de posición driverClassName por el nombre de clase de su controlador de la tabla anterior.

    <Context>
        <Resource
            name="jdbc/dbconnection"
            type="javax.sql.DataSource"
            url="${connURL}"
            driverClassName="<insert your driver class name>"
            username="${dbuser}"
            password="${dbpassword}"
        />
    </Context>
    
  3. Actualice el archivo web.xml de la aplicación para que use el origen de datos de su aplicación.

    <resource-env-ref>
        <resource-env-ref-name>jdbc/dbconnection</resource-env-ref-name>
        <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
    </resource-env-ref>
    

Recursos de nivel de servidor compartidos

Para agregar un origen de datos compartido de nivel de servidor, es necesario editar el archivo server.xml de Tomcat. En primer lugar, cargue un script de inicio y establezca la ruta de acceso al script en Configuración>Comando de inicio. Puede cargar el script de inicio mediante FTP.

El script de inicio realizará una transformación XSL al archivo server.xml y generará el archivo XML resultante en /usr/local/tomcat/conf/server.xml. El script de inicio debe instalar libxslt a través de APK. El archivo XSL y el script de inicio se pueden cargar a través de FTP. A continuación se muestra un script de inicio de ejemplo.

# Install libxslt. Also copy the transform file to /home/tomcat/conf/
apk add --update libxslt

# Usage: xsltproc --output output.xml style.xsl input.xml
xsltproc --output /home/tomcat/conf/server.xml /home/tomcat/conf/transform.xsl /usr/local/tomcat/conf/server.xml

El siguiente archivo XSL agrega un nuevo nodo de conector al archivo server.xml de Tomcat.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()" name="Copy">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@* | node()" mode="insertConnector">
    <xsl:call-template name="Copy" />
  </xsl:template>

  <xsl:template match="comment()[not(../Connector[@scheme = 'https']) and
                                 contains(., '&lt;Connector') and
                                 (contains(., 'scheme=&quot;https&quot;') or
                                  contains(., &quot;scheme='https'&quot;))]">
    <xsl:value-of select="." disable-output-escaping="yes" />
  </xsl:template>

  <xsl:template match="Service[not(Connector[@scheme = 'https'] or
                                   comment()[contains(., '&lt;Connector') and
                                             (contains(., 'scheme=&quot;https&quot;') or
                                              contains(., &quot;scheme='https'&quot;))]
                                  )]
                      ">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" mode="insertConnector" />
    </xsl:copy>
  </xsl:template>

  <!-- Add the new connector after the last existing Connnector if there's one -->
  <xsl:template match="Connector[last()]" mode="insertConnector">
    <xsl:call-template name="Copy" />

    <xsl:call-template name="AddConnector" />
  </xsl:template>

  <!-- ... or before the first Engine if there's no existing Connector -->
  <xsl:template match="Engine[1][not(preceding-sibling::Connector)]"
                mode="insertConnector">
    <xsl:call-template name="AddConnector" />

    <xsl:call-template name="Copy" />
  </xsl:template>

  <xsl:template name="AddConnector">
    <!-- Add new line -->
    <xsl:text>&#xa;</xsl:text>
    <!-- This is the new connector -->
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" 
               maxThreads="150" scheme="https" secure="true" 
               keystoreFile="${{user.home}}/.keystore" keystorePass="changeit"
               clientAuth="false" sslProtocol="TLS" />
  </xsl:template>

</xsl:stylesheet>

Finalización de la configuración

Por último, coloque los archivos JAR del controlador en la classpath de Tomcat y reinicie App Service.

  1. Asegúrese de que los archivos del controlador JDBC estén disponibles para el cargador de clases de Tomcat. Para ello, colóquelos en el directorio /home/site/lib. En Cloud Shell, ejecute az webapp deploy --type=lib para cada archivo JAR del controlador:
az webapp deploy --resource-group <group-name> --name <app-name> --src-path <jar-name>.jar --type=lib --path <jar-name>.jar

Si ha creado un origen de datos de nivel de servidor, reinicie la aplicación App Service de Linux. Tomcat restablecerá CATALINA_BASE a /home/tomcat y usará la configuración actualizadas.

Orígenes de datos de EAP de JBoss

Al registrar un origen de datos en JBoss EAP, hay tres pasos fundamentales: cargar el controlador JDBC, agregarlo como un módulo y registrar el módulo. App Service es un servicio de hospedaje sin estado, por lo que los comandos de configuración para agregar y registrar el módulo de origen de datos deben incluirse en un script y aplicarse cuando se inicie el contenedor.

  1. Obtenga el controlador JDBC de la base de datos.

  2. Cree un archivo de definición de módulo XML para el controlador JDBC. En el ejemplo siguiente se muestra una definición de módulo para PostgreSQL.

    <?xml version="1.0" ?>
    <module xmlns="urn:jboss:module:1.1" name="org.postgres">
        <resources>
        <!-- ***** IMPORTANT : REPLACE THIS PLACEHOLDER *******-->
        <resource-root path="/home/site/deployments/tools/postgresql-42.2.12.jar" />
        </resources>
        <dependencies>
            <module name="javax.api"/>
            <module name="javax.transaction.api"/>
        </dependencies>
    </module>
    
  3. Coloque los comandos de la CLI de JBoss en un archivo denominado jboss-cli-commands.cli. Los comandos de JBoss deben agregar el módulo y registrarlo como un origen de datos. En el ejemplo siguiente se muestran los comandos de la CLI de JBoss para PostgreSQL.

    #!/usr/bin/env bash
    module add --name=org.postgres --resources=/home/site/deployments/tools/postgresql-42.2.12.jar --module-xml=/home/site/deployments/tools/postgres-module.xml
    
    /subsystem=datasources/jdbc-driver=postgres:add(driver-name="postgres",driver-module-name="org.postgres",driver-class-name=org.postgresql.Driver,driver-xa-datasource-class-name=org.postgresql.xa.PGXADataSource)
    
    data-source add --name=postgresDS --driver-name=postgres --jndi-name=java:jboss/datasources/postgresDS --connection-url=${POSTGRES_CONNECTION_URL,env.POSTGRES_CONNECTION_URL:jdbc:postgresql://db:5432/postgres} --user-name=${POSTGRES_SERVER_ADMIN_FULL_NAME,env.POSTGRES_SERVER_ADMIN_FULL_NAME:postgres} --password=${POSTGRES_SERVER_ADMIN_PASSWORD,env.POSTGRES_SERVER_ADMIN_PASSWORD:example} --use-ccm=true --max-pool-size=5 --blocking-timeout-wait-millis=5000 --enabled=true --driver-class=org.postgresql.Driver --exception-sorter-class-name=org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter --jta=true --use-java-context=true --valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker
    
  4. Cree un script de inicio, startup_script.sh, que llame a los comandos de la CLI de JBoss. En el ejemplo siguiente se muestra cómo llamar a su jboss-cli-commands.cli. Más adelante, configurará App Service para ejecutar este script cuando se inicie el contenedor.

    $JBOSS_HOME/bin/jboss-cli.sh --connect --file=/home/site/deployments/tools/jboss-cli-commands.cli
    
  5. Mediante el cliente FTP de su elección, cargue el controlador JDBC, jboss-cli-commands.cli, startup_script.sh y la definición del módulo en /site/deployments/tools/.

  6. Configure el sitio para que ejecute startup_script.sh cuando se inicie el contenedor. En Azure Portal, vaya a Configuración>Configuración general>Comando de inicio. Establezca el campo de comando de inicio en /home/site/deployments/tools/startup_script.sh. Guarde los cambios mediante Guardar.

Para confirmar que el origen de datos se agregó al servidor JBoss, conéctese a su aplicación web mediante SSH y ejecute $JBOSS_HOME/bin/jboss-cli.sh --connect. Cuando se conecte a JBoss, ejecute /subsystem=datasources:read-resource para imprimir una lista de los orígenes de datos.

robots933456 en registros

Puede ver el mensaje siguiente en los registros del contenedor:

2019-04-08T14:07:56.641002476Z "-" - - [08/Apr/2019:14:07:56 +0000] "GET /robots933456.txt HTTP/1.1" 404 415 "-" "-"

Puede omitir este mensaje sin problemas. /robots933456.txt es una ruta de acceso de la dirección URL ficticia que utiliza App Service para comprobar si el contenedor es capaz de atender las solicitudes. Una respuesta 404 simplemente indica que la ruta de acceso no existe, pero permite a App Service saber que el contenedor está en buen estado y listo para responder a las solicitudes.

Selección de la versión del entorno de ejecución de Java

App Service permite a los usuarios elegir la versión principal de JVM (por ejemplo, Java 8 o Java 11) y la versión de revisión (por ejemplo, 1.8.0_232 o 11.0.5). También puede elegir que la versión de revisión se actualice automáticamente a medida que vayan estando disponibles. En la mayoría de los casos, las aplicaciones de producción deben usar versiones revisadas de JVM ancladas. Así se evitan interrupciones imprevistas durante la actualización automática de una versión revisada. Todas las aplicaciones web de Java usan JMS de 64 bits, lo que no es configurable.

Si usa Tomcat, puede optar por anclar la versión de revisión de Tomcat. En Windows, puede anclar las versiones de revisión de JVM y Tomcat de forma independiente. En Linux, puede anclar la versión de revisión de Tomcat; la versión de revisión de JVM también se ancla, pero no se puede configurar por separado.

Si elige anclar la versión secundaria, tiene que actualizar periódicamente la versión secundaria de JVM en la aplicación. Para asegurarse de que la aplicación se ejecute en la versión secundaria más reciente, cree un espacio de ensayo e incremente en él la versión secundaria. Cuando confirme que la aplicación se ejecuta correctamente en la nueva versión secundaria, puede intercambiar los espacios de ensayo y de producción.

JBoss EAP

Agrupación en clústeres en JBoss EAP

App Service admite la agrupación en clústeres para las versiones 7.4.1 y posteriores de JBoss EAP. Para habilitar la agrupación en clústeres, la aplicación web debe integrarse con una red virtual. Cuando la aplicación web se integra con una red virtual, se reinicia y la instalación de JBoss EAP se inicia automáticamente con una configuración en clúster. Las instancias de JBoss EAP se comunican a través de la subred especificada en la integración de red virtual, mediante los puertos que se muestran en la variable de entorno WEBSITES_PRIVATE_PORTS en tiempo de ejecución. Puede deshabilitar la agrupación en clústeres mediante la creación de una configuración de aplicación denominada WEBSITE_DISABLE_CLUSTERING con cualquier valor.

Nota:

Si va a habilitar la integración de red virtual con una plantilla de ARM, debe establecer manualmente la propiedad vnetPrivatePorts en un valor de 2. Si habilita la integración de red virtual desde la CLI o el portal, esta propiedad se establece automáticamente.

Cuando la agrupación en clústeres está habilitada, las instancias de EAP de JBoss usan el protocolo de detección de JGroups de FILE_PING para detectar nuevas instancias y conservar la información del clúster, como los miembros del clúster, sus identificadores y sus direcciones IP. En App Service, estos archivos se encuentran en /home/clusterinfo/. La primera instancia de EAP que se inicia obtiene los permisos de lectura y escritura en el archivo de pertenencia al clúster. Otras instancias leen el archivo, buscan el nodo principal y se coordinan con ese nodo para incluirlo en el clúster y agregarlo al archivo.

De manera opcional, los tipos de plan de App Service Premium V3 y V2 aislado se pueden distribuir entre zonas de disponibilidad para mejorar la resistencia y la confiabilidad de las cargas de trabajo críticas para la empresa. Esta arquitectura también se conoce como redundancia de zona. La característica de agrupación en clústeres de JBoss EAP es compatible con la característica de redundancia de zona.

Reglas de autoescalado

Al configurar reglas de escalado automático para el escalado horizontal, es importante eliminar las instancias de forma incremental (una a la vez) para asegurarse de que cada instancia eliminada puede transferir su actividad (por ejemplo, controlar una transacción de base de datos) a otro miembro del clúster. Al configurar las reglas de escalado automático en el portal para reducir verticalmente, use las siguientes opciones:

  • Operación: "Reducir recuento en"
  • Tiempo de finalización: "5 minutos" o superior
  • Recuento de instancias: 1

No es necesario agregar instancias de forma incremental (escalado horizontal), puede agregar varias instancias al clúster a la vez.

Planes de App Service de JBoss EAP

JBoss EAP solo está disponible en los tipos de plan Premium v3 y Aislado v2 de App Service. Los clientes que crearon un sitio de JBoss EAP en un nivel diferente durante la versión preliminar pública deben escalar verticalmente a un nivel de hardware Premium o Aislado para evitar un comportamiento inesperado.

Configuración de línea base de Tomcat en App Services

Los desarrolladores de Java pueden personalizar la configuración del servidor, solucionar problemas e implementar aplicaciones en Tomcat con confianza si saben sobre el archivo de server.xml y los detalles de configuración de Tomcat. Entre las posibles personalizaciones se incluyen las siguientes:

  • Personalización de la configuración de Tomcat: al reconocer el archivo server.xml y los detalles de configuración de Tomcat, los desarrolladores pueden ajustar de manera precisa la configuración del servidor para satisfacer las necesidades de sus aplicaciones.
  • Depuración: cuando se implementa una aplicación en un servidor de Tomcat, los desarrolladores deben conocer la configuración del servidor para depurar los problemas que puedan surgir. Esto incluye comprobar los registros del servidor, examinar los archivos de configuración e identificar los errores que podrían producirse.
  • Solución de problemas de Tomcat: inevitablemente, los desarrolladores de Java encontrarán problemas con su servidor Tomcat, como problemas de rendimiento o errores de configuración. Al reconocer el archivo de server.xml y los detalles de configuración de Tomcat, los desarrolladores pueden diagnosticar y solucionar estos problemas rápidamente, lo que puede ahorrar tiempo y esfuerzo.
  • Implementación de aplicaciones en Tomcat: para implementar una aplicación web de Java en Tomcat, los desarrolladores deben saber cómo configurar el archivo server.xml y otras opciones de Configuración de Tomcat. Reconocer estos detalles es esencial para implementar aplicaciones correctamente y asegurarse de que se ejecutan sin problemas en el servidor.

Al crear una aplicación con Tomcat integrado para hospedar la carga de trabajo de Java (un archivo WAR o un archivo JAR), hay ciertas opciones de configuración que obtendrá para la configuración de Tomcat. Puede consultar el Documentación oficial de Apache Tomcat para obtener información detallada, incluida la configuración predeterminada para Tomcat Web Server.

Además, hay ciertas transformaciones que se aplican aún más sobre la server.xml para la distribución de Tomcat al iniciarse. Se trata de transformaciones en la configuración conector, host y válvula.

Tenga en cuenta que las versiones más recientes de Tomcat tienen server.xml (8.5.58 y 9.0.38 en adelante). Las versiones anteriores de Tomcat no usan transformaciones y pueden tener un comportamiento diferente como resultado.

Conector

<Connector port="${port.http}" address="127.0.0.1" maxHttpHeaderSize="16384" compression="on" URIEncoding="UTF-8" connectionTimeout="${site.connectionTimeout}" maxThreads="${catalina.maxThreads}" maxConnections="${catalina.maxConnections}" protocol="HTTP/1.1" redirectPort="8443"/>
  • maxHttpHeaderSize se establezca en 16384.
  • URIEncoding se establezca en UTF-8.
  • conectionTimeout se establece en WEBSITE_TOMCAT_CONNECTION_TIMEOUT, cuyo valor predeterminado es 240000
  • maxThreads se establece en WEBSITE_CATALINA_MAXTHREADS, que tiene como valor predeterminado 200
  • maxConnections se establece en WEBSITE_CATALINA_MAXCONNECTIONS, que tiene como valor predeterminado 10000

Nota:

La configuración de connectionTimeout, maxThreads y maxConnections se puede ajustar con la configuración de la aplicación

A continuación se muestran comandos de la CLI de ejemplo que puede usar para modificar los valores de conectionTimeout, maxThreads o maxConnections:

az webapp config appsettings set --resource-group myResourceGroup --name myApp --settings WEBSITE_TOMCAT_CONNECTION_TIMEOUT=120000
az webapp config appsettings set --resource-group myResourceGroup --name myApp --settings WEBSITE_CATALINA_MAXTHREADS=100
az webapp config appsettings set --resource-group myResourceGroup --name myApp --settings WEBSITE_CATALINA_MAXCONNECTIONS=5000
  • El conector usa la dirección del contenedor en lugar de 127.0.0.1

Host

<Host appBase="${site.appbase}" xmlBase="${site.xmlbase}" unpackWARs="${site.unpackwars}" workDir="${site.tempdir}" errorReportValveClass="com.microsoft.azure.appservice.AppServiceErrorReportValve" name="localhost" autoDeploy="true">
  • appBase se establece en AZURE_SITE_APP_BASE, que tiene como valor predeterminado local WebappsLocalPath
  • xmlBase se establece en AZURE_SITE_HOME, que tiene como valor predeterminado /site/wwwroot
  • unpackWARs se establece en AZURE_UNPACK_WARS, que tiene como valor predeterminado true
  • workDir se establece en JAVA_TMP_DIR, que tiene como valor predeterminado TMP
  • errorReportValveClass usa nuestra válvula de informe de errores personalizada

Válvula

<Valve prefix="site_access_log.${catalina.instance.name}" pattern="%h %l %u %t &quot;%r&quot; %s %b %D %{x-arr-log-id}i" directory="${site.logdir}/http/RawLogs" maxDays="${site.logRetentionDays}" className="org.apache.catalina.valves.AccessLogValve" suffix=".txt"/>
  • directory se establece en AZURE_LOGGING_DIR, que tiene como valor predeterminado home\logFiles
  • maxDays es WEBSITE_HTTPLOGGING_RETENTION_DAYS, que tiene como valor predeterminado 0 [para siempre]

En Linux, tiene toda la misma personalización, además de:

  • Agrega algunas páginas de error e informes a la válvula:
               <xsl:attribute name="appServiceErrorPage">
                   <xsl:value-of select="'${appService.valves.appServiceErrorPage}'"/>
               </xsl:attribute>

               <xsl:attribute name="showReport">
                   <xsl:value-of select="'${catalina.valves.showReport}'"/>
               </xsl:attribute>

               <xsl:attribute name="showServerInfo">
                   <xsl:value-of select="'${catalina.valves.showServerInfo}'"/>
               </xsl:attribute>

Pasos siguientes

Visite el centro de Azure para desarrolladores de Java para encontrar guías de inicio rápido de Azure, tutoriales y documentación de referencia de Java.