Configurar um aplicativo Java para o Serviço de Aplicativo do Azure

Observação

Para aplicativos Spring, é recomendável usar o Aplicativos Spring do Azure. No entanto, você ainda pode usar o Serviço de Aplicativo do Azure como um destino. Consulte Diretrizes de Destino da Carga de Trabalho Java para obter orientação.

O Serviço de Aplicativo do Azure permite que os desenvolvedores de Java compilem, implantem e dimensionem rapidamente os aplicativos Web Java SE, Tomcat e JBoss EAP em um serviço totalmente gerenciado. Implante aplicativos com plug-ins do Maven na linha de comando ou em editores, como IntelliJ, Eclipse ou Visual Studio Code.

Este guia mostra os principais conceitos e instruções para desenvolvedores de Java que usam o Serviço de Aplicativo. Se você nunca tiver usado o Serviço de Aplicativo do Azure, leia o Início rápido do Java primeiro. Dúvidas gerais sobre como usar o Serviço de Aplicativo que não são específicas do desenvolvimento em Java são respondidas nas Perguntas frequentes sobre o Serviço de Aplicativo.

Mostrar versão do Java

Para mostrar a versão atual do Java, execute o seguinte comando no Cloud Shell:

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

Para mostrar todas as versões do Java compatíveis, execute o seguinte comando no Cloud Shell:

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

Para mostrar a versão atual do Java, execute o seguinte comando no Cloud Shell:

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

Para mostrar todas as versões do Java compatíveis, execute o seguinte comando no Cloud Shell:

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

Para obter mais informações sobre o suporte à versão, confira Política de suporte de runtime de linguagem do Serviço de Aplicativo.

Implantação do aplicativo

Ferramentas de compilação

Maven

Com o Plug-in do Maven para aplicativos Web do Azure você pode preparar seu projeto Maven Java para o Aplicativo Web do Azure facilmente com um comando na raiz do projeto:

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

Esse comando adiciona um plug-in azure-webapp-maven-plugin e uma configuração relacionada solicitando que você selecione um Aplicativo Web do Azure existente ou crie um. Em seguida, você poderá implantar seu aplicativo Java no Azure usando o seguinte comando:

mvn package azure-webapp:deploy

Veja uma configuração de exemplo em 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 o Plug-in Gradle para Aplicativos Web do Azure adicionando o plug-in ao seu build.gradle:

    plugins {
      id "com.microsoft.azure.azurewebapp" version "1.7.1"
    }
    
  2. Configurar os detalhes do aplicativo Web. Os recursos correspondentes do Azure serão criados se eles não existirem. Aqui está um exemplo de configuração. Para obter detalhes, consulte 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. Implantar com um comando.

    gradle azureWebAppDeploy
    

IDEs

O Azure fornece uma experiência perfeita de desenvolvimento do Serviço de Aplicativo Java em Java IDEs populares, incluindo:

Kudu API

Java SE

Para implantar arquivos .jar em Java SE, use o ponto de extremidade /api/publish/ do site do Kudu. Para obter mais informações sobre essa API, confira essa documentação.

Observação

Seu aplicativo .jar deve ser nomeado app.jar para o Serviço de Aplicativo identificar e executar seu aplicativo. O plug-in do Maven faz isso para você automaticamente durante a implantação. Se não desejar renomear o JAR para app.jar, você poderá carregar um script de shell com o comando para executar o JAR. Cole o caminho absoluto desse script na caixa de texto Arquivo de inicialização, na seção Configuração do portal. O script de inicialização não é executado por meio do diretório no qual ele é colocado. Portanto, sempre use caminhos absolutos para fazer referência a arquivos em seu script de inicialização (por exemplo: java -jar /home/myapp/myapp.jar).

Tomcat

Para implantar arquivos .war para Tomcat, use o ponto de extremidade /api/wardeploy/ para executar POST de seu arquivo morto. Para obter mais informações sobre essa API, confira essa documentação.

JBoss EAP

Para implantar arquivos .war para JBoss, use o ponto de extremidade /api/wardeploy/ para executar POST no arquivo morto. Para obter mais informações sobre essa API, confira essa documentação.

Para implantar arquivos .ear, use o FTP. Seu aplicativo .ear é implantado na raiz de contexto definida na configuração do aplicativo. Por exemplo, se a raiz de contexto do aplicativo for <context-root>myapp</context-root>, você poderá procurar o site no caminho /myapp: http://my-app-name.azurewebsites.net/myapp. Se quiser que seu aplicativo Web seja atendido no caminho raiz, verifique se o aplicativo define a raiz de contexto para o caminho raiz: <context-root>/</context-root>. Para obter mais informações, consulte Definir a raiz de contexto de um aplicativo Web.

Não implante seu .war ou .jar usando FTP. A ferramenta FTP foi projetada para carregar os scripts de inicialização, dependências ou outros arquivos de runtime. Não é a opção ideal para a implantação de aplicativos Web.

Aplicativos de registro em log e depuração

Relatórios de desempenho, visualizações de tráfego e verificações de integridade estão disponíveis para cada aplicativo por meio do portal do Azure. Para obter mais informações, confira Visão geral de diagnóstico do Serviço de Aplicativo do Azure.

Logs de diagnóstico de fluxo

Para acessar os logs de console gerados dentro do código do aplicativo no Serviço de Aplicativo, ative o log de diagnóstico executando o seguinte comando no Cloud Shell:

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

Os valores possíveis para --level são Error, Warning, Info e Verbose. Cada nível seguinte inclui o anterior. Por exemplo: Error inclui apenas mensagens de erro e Verbose inclui todas as mensagens.

Depois que o log de diagnósticos estiver ativado, execute o seguinte comando para ver o fluxo de logs:

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

Se você não vir os logs do console imediatamente, verifique novamente após 30 segundos.

Observação

Você também pode inspecionar os arquivos de log do navegador em https://<app-name>.scm.azurewebsites.net/api/logs/docker.

Para interromper o streaming de log a qualquer momento, digite Ctrl+C.

Você pode acessar os logs do console gerados de dentro do contêiner.

Primeiro, ative o log do contêiner executando o seguinte comando:

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

Substitua <app-name> e <resource-group-name> pelos nomes apropriados para seu aplicativo Web.

Depois que o log do contêiner estiver ativado, execute o seguinte comando para ver o fluxo de log:

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

Se você não vir os logs do console imediatamente, verifique novamente após 30 segundos.

Para interromper o streaming de log a qualquer momento, digite Ctrl+C.

Você também pode inspecionar os arquivos de log em um navegador em https://<app-name>.scm.azurewebsites.net/api/logs/docker.

Para obter mais informações, confira Logs de fluxo no Cloud Shell.

Acesso ao console SSH

Para abrir uma sessão SSH direta com seu contêiner, seu aplicativo deve estar em execução.

Cole a seguinte URL no seu navegador e substitua <app-name> pelo nome do aplicativo:

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

Se você ainda não estiver autenticado, será necessário autenticar com sua assinatura do Azure para se conectar. Uma vez autenticado, consulte um shell no navegador, onde você pode executar comandos dentro de seu contêiner.

Conexão SSH

Observação

Quaisquer alterações feitas fora do diretório /home são armazenadas no próprio contêiner e não persistem além da reinicialização do aplicativo.

Para abrir uma sessão SSH remota no seu computador local, consulte Abrir a sessão SSH no shell remoto.

Ferramentas de solução de problemas

As imagens Java internas são baseadas no sistema operacional Alpine Linux. Use o gerenciador de pacotes apk para instalar quaisquer ferramentas ou comandos de solução de problemas.

Java Profiler

Todos os runtimes do Java no Serviço de Aplicativo do Azure vêm com o Gravador de Voo do JDK para criação de perfil de cargas de trabalho Java. Você poderá usá-lo para registrar eventos da JVM, do sistema e do aplicativo e solucionar problemas nos aplicativos.

Para saber mais sobre o Java Profiler, visite a documentação do Aplicativo Azure Insights.

Flight Recorder

Todos os runtimes do Java no Serviço de Aplicativo vêm com o Gravador de Voo do Java. Você poderá usá-lo para registrar eventos da JVM, do sistema e do aplicativo e solucionar problemas nos aplicativos do Java.

Gravação programada

Para fazer uma gravação programada, você precisa da PID (ID do processo) do aplicativo do Java. Para encontrar o PID, abra um navegador para o site do SCM do aplicativo Web em https://<your-site-name>.scm.azurewebsites.net/ProcessExplorer/. Esta página mostra os processos em execução no aplicativo Web. Localize o processo denominado "Java" na tabela e copie a PID (ID do processo) correspondente.

Em seguida, abra o Console de Depuração na barra de ferramentas superior do site do SCM e execute o comando a seguir. Substitua <pid> pela ID do processo que você copiou anteriormente. Esse comando inicia uma gravação do criador de perfil de 30 segundos do aplicativo Java e gerará um arquivo denominado timed_recording_example.jfr no diretório C:\home.

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

SSH no Serviço de Aplicativo e execute o comando jcmd para ver uma lista de todos os processos Java em execução. Além do próprio jcmd, você deve ver seu aplicativo Java em execução com um número de pid (ID do processo).

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

Execute o comando a seguir para iniciar uma gravação de 30 segundos da JVM. Ele cria o perfil da JVM e um arquivo JFR chamado jfr_example.jfr no diretório inicial. (Substitua 116 pelo pid do seu aplicativo Java.)

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

Durante o intervalo de 30 segundos, é possível validar a gravação executando jcmd 116 JFR.check. O comando mostra todas as gravações para o processo do Java especificado.

Gravação contínua

Use o Gravador de Voo do Java para criar um perfil contínuo de seu aplicativo do Java com impacto mínimo no desempenho do tempo de execução. Para fazer isso, execute o comando da CLI do Azure a seguir para criar uma Configuração de Aplicativo chamada JAVA_OPTS com a configuração necessária. O conteúdo da Configuração de Aplicativo JAVA_OPTS é passado para o comando java quando o aplicativo é iniciado.

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

Uma vez que a gravação começa, é possível despejar os dados da gravação atual a qualquer momento usando o comando JFR.dump.

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

Analisar os arquivos .jfr

Use o FTPS para baixar o arquivo JFR no seu computador local. Para analisar o arquivo JFR, faça download e instale o Controle de Missão Java. Para obter instruções sobre o Controle de Missão Java, confira a documentação do JMC e as instruções de instalação.

Registro em log do aplicativo

Habilite o registro em log de aplicativos por meio do portal do Azure ou da CLI do Azure para configurar o Serviço de Aplicativo do Azure para gravar a saída do console padrão do aplicativo e os fluxos de erro do console padrão no sistema de arquivos local ou no Armazenamento de Blobs do Azure. O registro em log na instância do sistema de arquivos do Serviço de Aplicativo local será desabilitado 12 horas após ser configurado. Se você precisar de uma retenção mais longa, configure o aplicativo para gravar a saída em um contêiner do armazenamento de blobs. Seus logs de aplicativos Java e Tomcat podem ser encontrados no diretório /home/LogFiles/Application/ .

Habilite o registro em log de aplicativos por meio do portal do Azure ou da CLI do Azure para configurar o Serviço de Aplicativo do Azure para gravar a saída do console padrão do aplicativo e os fluxos de erro do console padrão no sistema de arquivos local ou no Armazenamento de Blobs do Azure. Se você precisar de uma retenção mais longa, configure o aplicativo para gravar a saída em um contêiner do armazenamento de blobs. Seus logs de aplicativos Java e Tomcat podem ser encontrados no diretório /home/LogFiles/Application/ .

O registro em log do Armazenamento de Blobs do Azure para aplicativos com base no Linux pode ser configurado apenas usando o Azure Monitor.

Se o aplicativo usar Logback ou Log4j para rastreamento, será possível encaminhá-los para revisão no Azure Application Insights usando as instruções de configuração de estrutura de registros em Explorar os logs de rastreamento de Java no Application Insights.

Observação

Devido à vulnerabilidade conhecida CVE-2021-44228, use o Log4j versão 2.16 ou posterior.

Personalização e ajuste

O Serviço de Aplicativo do Azure é compatível com o ajuste e a personalização de caixas por meio do portal e da CLI do Azure. Examine os seguintes artigos para saber mais sobre a configuração de aplicativos Web específica para não Java:

Copiar conteúdo do aplicativo localmente

Defina a configuração JAVA_COPY_ALL do aplicativo como true para copiar o conteúdo do aplicativo para o trabalho local a partir do sistema de arquivos compartilhado. Essa configuração ajuda a resolver problemas de bloqueio de arquivo.

Definir opções de runtime do Java

Para definir a memória alocada ou outras opções de runtime da JVM, crie uma configuração de aplicativo denominada JAVA_OPTS com as opções. O Serviço de Aplicativo passa essa configuração como uma variável de ambiente para o runtime do Java quando ele é iniciado.

No portal do Azure, em Configurações do aplicativo para o aplicativo Web, crie uma configuração de aplicativo denominada JAVA_OPTS para Java SE ou CATALINA_OPTS para Tomcat que inclui as configurações, como -Xms512m -Xmx1204m.

Para definir a configuração de aplicativo do plug-in do Maven, adicione marcas de configuração/valor à seção de plug-in do Azure. O seguinte exemplo define um tamanho de heap de Java específico mínimo e máximo:

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

Observação

Você não precisa criar um arquivo web.config ao usar o Tomcat no Serviço de Aplicativo do Windows.

Os desenvolvedores que executam um único aplicativo com um slot de implantação no Plano do Serviço de Aplicativo podem usar as seguintes opções:

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

Ao ajustar as configurações de heap do aplicativo, examine os detalhes do Plano do Serviço de Aplicativo e considere os vários aplicativos e slots de implantação necessários para encontrar a alocação de memória ideal.

Ativar os soquetes da Web

Ative o suporte para soquetes da Web no portal do Azure, nas Configurações de aplicativo. É necessário reiniciar o aplicativo para a configuração entrar em vigor.

Ative o suporte para soquete da Web usando a CLI do Azure com o seguinte comando:

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

Depois, reinicie o aplicativo:

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

Definir a codificação de caractere padrão

No portal do Azure, em Configurações do aplicativo para o aplicativo Web, crie uma configuração de aplicativo denominada JAVA_OPTS com o valor -Dfile.encoding=UTF-8.

Como alternativa, é possível definir a configuração do aplicativo usando o plug-in do Maven do Serviço de Aplicativo. Adicione as marcas de nome e valor de configuração à configuração do plug-in:

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

Pré-compilar arquivos JSP

Para melhorar o desempenho dos aplicativos Tomcat, você pode compilar seus arquivos JSP antes de implantar no Serviço de Aplicativo. Você pode usar o plug-in do Maven fornecido pelo Apache Sling ou usando este arquivo de compilação Ant.

Aplicativos seguros

Os aplicativos Java em execução no Serviço de Aplicativo têm o mesmo conjunto de melhores práticas de segurança que outros aplicativos.

Autenticar usuários (autenticação fácil)

Configure a autenticação de aplicativo no portal do Azure com a opção Autenticação e Autorização. A partir daí, você pode habilitar a autenticação usando o Microsoft Entra ID ou credenciais de redes sociais, como Facebook, Google ou GitHub. A configuração do portal do Azure só funciona ao configurar um único provedor de autenticação. Para obter mais informações, confira Configurar seu aplicativo do Serviço de Aplicativo para usar a entrada do Microsoft Entra e os artigos relacionados para outros provedores de identidade. Caso precise habilitar vários provedores de entrada, siga as instruções em Personalizar entradas e saídas.

Java SE

Os desenvolvedores do Spring Boot podem usar o inicializador do Microsoft Entra Spring Boot para proteger aplicativos usando anotações e APIs familiares do Spring Security. Lembre-se de aumentar o tamanho máximo do cabeçalho no arquivo application.properties. Sugerimos um valor igual a 16384.

Tomcat

Seu aplicativo Tomcat pode acessar as declarações do usuário diretamente do servlet, convertendo o objeto Principal em um objeto Map. O objeto Map mapeia cada tipo de declaração para uma coleção de declarações para esse tipo. No exemplo de código a seguir, request há uma instância de HttpServletRequest.

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

Agora você pode inspecionar o objeto Map para qualquer declaração específica. Por exemplo, o trecho de código a seguir itera todos os tipos de declaração e imprime o conteúdo de cada coleção.

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 desconectar os usuários, use o caminho /.auth/ext/logout. Para executar outras ações, consulte a documentação sobre Personalizar entradas e saídas. Também há documentação oficial na interface HttpServletRequest do Tomcat e seus métodos. Os seguintes métodos de servlet também são hidratados com base na sua configuração do Serviço de Aplicativo:

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

Para desabilitar esse recurso, crie uma Configuração de Aplicativo chamada WEBSITE_AUTH_SKIP_PRINCIPAL com um valor de 1. Para desabilitar todos os filtros de servlet adicionados pelo Serviço de Aplicativo, crie uma configuração chamada WEBSITE_SKIP_FILTERS com um valor 1.

Configurar TLS/SSL

Para carregar um certificado TLS/SSL existente e associá-lo ao nome de domínio do aplicativo, siga as instruções em Proteger um nome DNS personalizado com uma associação TLS/SSL no Serviço de Aplicativo do Azure. Também é possível configurar o aplicativo para impor o TLS/SSL.

Usar referências de Key Vault

O Azure KeyVault fornece gerenciamento secreto centralizado com políticas de acesso e histórico de auditoria. Você pode armazenar segredos (como senhas ou cadeias de conexão) no KeyVault e acessar esses segredos no seu aplicativo por meio de variáveis de ambiente.

Primeiro, siga as instruções para conceder ao seu aplicativo acesso a um cofre de chaves e fazer uma referência do KeyVault ao seu segredo em uma Configuração do Aplicativo. Você pode validar que a referência seja resolvida no segredo imprimindo a variável de ambiente enquanto acessa remotamente o terminal do Serviço de Aplicativo.

Para injetar esses segredos em seu arquivo de configuração Spring ou Tomcat, use a sintaxe de injeção de variável de ambiente (${MY_ENV_VAR}). Para arquivos de configuração do Spring, confira esta documentação sobre configurações externas.

Usar o Repositório de Chaves Java

Por padrão, todos os certificados públicos ou privados carregados no Serviço de Aplicativo do Linux são carregados nos respectivos Repositório de Chaves do Java quando o contêiner for iniciado. Após carregar seu certificado, você precisará reiniciar o Serviço de Aplicativo para que ele seja carregado no Repositório de Chaves Java. Os certificados públicos são carregados no Repositório de Chaves em $JRE_HOME/lib/security/cacerts e os certificados privados são armazenados em $JRE_HOME/lib/security/client.jks.

Mais configurações podem ser necessárias para criptografar sua conexão JDBC com certificados no Repositório de Chaves do Java. Confira a documentação para o driver JDBC escolhido.

Inicializar o Repositório de Chaves Java

Para inicializar o objeto import java.security.KeyStore, carregue o arquivo do repositório de chaves com a senha. A senha padrão para ambos os repositórios de chaves é 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());

Carregar manualmente o repositório de chaves

Você pode carregar certificados manualmente no repositório de chaves. Crie uma configuração de aplicativo, SKIP_JAVA_KEYSTORE_LOAD, com um valor de 1 para desabilitar o Serviço de Aplicativo do carregamento dos certificados no repositório de chaves automaticamente. Todos os certificados públicos carregados no Serviço de Aplicativo por meio do portal do Azure são armazenados em /var/ssl/certs/. Os certificados particulares são armazenados em /var/ssl/private/.

Você pode interagir ou depurar a Java Key Tool abrindo uma conexão SSH no seu Serviço de Aplicativo e executando o comando keytool. Confira a documentação da Key Tool para obter uma lista de comandos. Para obter mais informações sobre a API KeyStore, confira a documentação oficial.

Configurar plataformas APM

Esta seção mostra como conectar aplicativos Java implantados no Serviço de Aplicativo do Azure com o Application Insights do Azure Monitor, o NewRelic e as APM (plataformas de monitoramento de desempenho) do aplicativo AppDynamics.

Configurar o Application Insights

O Application Insights do Azure Monitor é um serviço de monitoramento de aplicativo nativo de nuvem que permite que os clientes observem falhas, gargalos e padrões de uso para melhorar o desempenho do aplicativo e reduzir o tempo médio de resolução (MTTR). Com alguns cliques ou comandos da CLI, você pode habilitar o monitoramento para os aplicativos Node.js ou Java, logs de coleta automática, métricas e rastreamentos distribuídos, eliminando a necessidade de incluir um SDK no aplicativo. Confira a documentação do Application Insights para obter mais informações sobre as configurações de aplicativo disponíveis para configurar o agente.

Portal do Azure

Para habilitar o Application Insights no portal do Azure, acesse o Application Insights no menu à esquerda e selecione Ativar o Application Insights. Por padrão, é usado um novo recurso do Application Insights com o mesmo nome que o aplicativo Web. Você pode optar por usar um recurso existente do Application Insights ou alterar o nome. Por fim, selecione Aplicar na parte inferior.

CLI do Azure

Para habilitar por meio da CLI do Azure, é necessário criar um recurso do Application Insights e definir algumas configurações de aplicativo no portal do Azure para conectar o Application Insights ao aplicativo Web.

  1. Habilite a extensão do Applications Insights

    az extension add -n application-insights
    
  2. Crie um recurso do Application Insights usando o seguinte comando da CLI. Substitua os espaços reservados pelo nome e grupo do recurso desejado.

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

    Observe os valores para connectionString e instrumentationKey, você precisará desses valores na próxima etapa.

    Para recuperar uma lista de outros locais, execute az account list-locations.

  1. Defina a chave de instrumentação, a cadeia de conexão e a versão do agente de monitoramento como configurações do aplicativo no aplicativo Web. Substitua <instrumentationKey> e <connectionString> pelos valores das etapas anteriores.

    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. Defina a chave de instrumentação, a cadeia de conexão e a versão do agente de monitoramento como configurações do aplicativo no aplicativo Web. Substitua <instrumentationKey> e <connectionString> pelos valores das etapas anteriores.

    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"
    

Configurar o New Relic

  1. Criar uma conta de NewRelic em NewRelic.com

  2. Faça download do agente Java do NewRelic. Ele tem um nome de arquivo semelhante a newrelic-java-x.x.x.zip.

  3. Copie sua chave de licença, você precisará dela para configurar o agente mais tarde.

  4. SSH em sua instância do Serviço de Aplicativo e crie um diretório /home/site/wwwroot/apm.

  5. Carregue os arquivos do agente NewRelic Java descompactados em um diretório em /home/site/wwwroot/apm. Os arquivos do seu agente devem estar em /home/site/wwwroot/apm/newrelic.

  6. Modifique o arquivo YAML em /home/site/wwwroot/apm/newrelic/newrelic.yml e substitua o valor de licença de espaço reservado pela sua chave de licença.

  7. No portal do Azure, navegue até seu aplicativo no serviço de aplicativo e criar uma nova configuração de aplicativo.

    • Para aplicativos Java SE, crie uma variável de ambiente denominada JAVA_OPTS com o valor -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar.
    • Para Tomcat, crie uma variável de ambiente denominada CATALINA_OPTS com o valor -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar.
  1. Criar uma conta de NewRelic em NewRelic.com

  2. Faça download do agente Java do NewRelic. Ele tem um nome de arquivo semelhante a newrelic-java-x.x.x.zip.

  3. Copie sua chave de licença, você precisará dela para configurar o agente mais tarde.

  4. SSH em sua instância do Serviço de Aplicativo e crie um diretório /home/site/wwwroot/apm.

  5. Carregue os arquivos do agente NewRelic Java descompactados em um diretório em /home/site/wwwroot/apm. Os arquivos do seu agente devem estar em /home/site/wwwroot/apm/newrelic.

  6. Modifique o arquivo YAML em /home/site/wwwroot/apm/newrelic/newrelic.yml e substitua o valor de licença de espaço reservado pela sua chave de licença.

  7. No portal do Azure, navegue até seu aplicativo no serviço de aplicativo e criar uma nova configuração de aplicativo.

    • Para aplicativos Java SE, crie uma variável de ambiente denominada JAVA_OPTS com o valor -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar.
    • Para Tomcat, crie uma variável de ambiente denominada CATALINA_OPTS com o valor -javaagent:/home/site/wwwroot/apm/newrelic/newrelic.jar.

Se você já tiver uma variável de ambiente para JAVA_OPTS ou CATALINA_OPTS, acrescente o -javaagent:/... opção ao final do valor atual.

Configurar o AppDynamics

  1. Criar uma conta do AppDynamics em AppDynamics.com

  2. Faça download do agente Java no site da AppDynamics. O nome do arquivo é semelhante a AppServerAgent-x.x.x.xxxxx.zip

  3. Use o console do Kudu para criar um novo diretório /home/site/wwwroot/apm.

  4. Carregue os arquivos do agente de Java descompactados em um diretório em /home/site/wwwroot/apm. Os arquivos do seu agente devem estar em /home/site/wwwroot/apm/appdynamics.

  5. No portal do Azure, navegue até seu aplicativo no serviço de aplicativo e criar uma nova configuração de aplicativo.

    • Para aplicativos Java SE, crie uma variável de ambiente denominada JAVA_OPTS com o valor -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name> quando <app-name> for o nome do Serviço de Aplicativo.
    • Para aplicativos Tomcat, crie uma variável de ambiente denominada CATALINA_OPTS com o valor -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name> quando <app-name> for o nome do Serviço de Aplicativo.
  1. Criar uma conta do AppDynamics em AppDynamics.com

  2. Faça download do agente Java no site da AppDynamics. O nome do arquivo é semelhante a AppServerAgent-x.x.x.xxxxx.zip

  3. SSH em sua instância do Serviço de Aplicativo e crie um diretório /home/site/wwwroot/apm.

  4. Carregue os arquivos do agente de Java descompactados em um diretório em /home/site/wwwroot/apm. Os arquivos do seu agente devem estar em /home/site/wwwroot/apm/appdynamics.

  5. No portal do Azure, navegue até seu aplicativo no serviço de aplicativo e criar uma nova configuração de aplicativo.

    • Para aplicativos Java SE, crie uma variável de ambiente denominada JAVA_OPTS com o valor -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name> quando <app-name> for o nome do Serviço de Aplicativo.
    • Para aplicativos Tomcat, crie uma variável de ambiente denominada CATALINA_OPTS com o valor -javaagent:/home/site/wwwroot/apm/appdynamics/javaagent.jar -Dappdynamics.agent.applicationName=<app-name> quando <app-name> for o nome do Serviço de Aplicativo.

Observação

Se você já tiver uma variável de ambiente para JAVA_OPTS ou CATALINA_OPTS, acrescente o -javaagent:/... opção ao final do valor atual.

Configurar fonte de dados

Java SE

Para conectar-se a fontes de dados nos aplicativos Spring Boot, sugerimos criar cadeias de conexão e injetá-las no arquivo application.properties.

  1. Na seção "Configuração" da página Serviço de Aplicativo, defina um nome para a cadeia de caracteres, cole sua cadeia de conexão JDBC no campo de valor e defina o tipo como "Personalizado". Opcionalmente, defina essa cadeia de conexão como configuração de slot.

    Essa cadeia de conexão é acessível ao nosso aplicativo como uma variável de ambiente nomeada CUSTOMCONNSTR_<your-string-name>. Por exemplo, CUSTOMCONNSTR_exampledb.

  2. No arquivo application.properties, faça referência a essa cadeia de conexão com o nome da variável de ambiente. Para o nosso exemplo, usaríamos o seguinte:

    app.datasource.url=${CUSTOMCONNSTR_exampledb}
    

Confira a documentação do Spring Boot sobre acesso a dados e configurações externalizadas para obter mais informações sobre este tópico.

Tomcat

Essas instruções se aplicam a todas as conexões de banco de dados. Você precisa preencher os espaços reservados com nome de classe do driver do banco de dados escolhido e o arquivo JAR. É fornecida uma tabela com nomes de classe e downloads de driver para bancos de dados comuns.

Banco de dados Nome de Classe do Driver Driver JDBC
PostgreSQL org.postgresql.Driver Download
MySQL com.mysql.jdbc.Driver Baixar (Selecione "Independente de Plataforma")
SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver Download

Para configurar o Tomcat para usar a JDBC (Conectividade de Banco de Dados Java) ou a JPA (API de Persistência Java), primeiro personalize a variável de ambiente CATALINA_OPTS lida em Tomcat na inicialização do backup. Defina esses valores por meio de uma configuração de aplicativo no plug-in Maven do Serviço de Aplicativo:

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

Ou defina as variáveis de ambiente na página Configuração>Configurações de Aplicativo no portal do Azure.

Em seguida, determine se a fonte de dados deve estar disponível para um aplicativo ou para todos os aplicativos em execução no servlet do Tomcat.

Fontes de dados no nível do aplicativo

  1. Crie um arquivo context.xml no diretório META-INF/ do seu projeto. Crie o diretório META-INF/ se ele não existir.

  2. Em context.xml, adicione um elemento Context para vincular a fonte de dados a um endereço JNDI. Substitua o espaço reservado driverClassName pelo nome de classe do seu driver da tabela acima.

    <Context>
        <Resource
            name="jdbc/dbconnection"
            type="javax.sql.DataSource"
            url="${connURL}"
            driverClassName="<insert your driver class name>"
            username="${dbuser}"
            password="${dbpassword}"
        />
    </Context>
    
  3. Atualize o web.xml do aplicativo para usar a fonte de dados no aplicativo.

    <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 compartilhados no nível do servidor

As instalações do Tomcat no Serviço de Aplicativo no Windows existem no espaço compartilhado no plano de Serviço de Aplicativo. Não é possível modificar diretamente uma instalação do Tomcat para a configuração de todo o servidor. Para fazer alterações de configuração no nível do servidor na instalação do Tomcat, você deve copiar o Tomcat para uma pasta local, na qual você pode modificar a configuração do Tomcat.

Automatizar a criação do Tomcat personalizado na inicialização do aplicativo

Você pode usar um script de inicialização para executar ações antes que um aplicativo Web seja iniciado. O script de inicialização para personalizar o Tomcat precisa concluir as seguintes etapas:

  1. Verifique se o Tomcat já foi copiado e configurado localmente. Se foi, o script de inicialização pode terminar aqui.
  2. Copie o Tomcat localmente.
  3. Faça as alterações de configuração necessárias.
  4. Indica que a configuração foi concluída com êxito.

Para aplicativos do Windows, crie um arquivo chamado startup.cmd ou startup.ps1 no diretório wwwroot. Esse arquivo é executado automaticamente antes do início do servidor Tomcat.

Aqui está um script do PowerShell que conclui essas etapas:

    # 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
Transformações

Um caso de uso comum para personalizar uma versão do Tomcat é modificar os arquivos de configuração server.xml, context.xml ou web.xml do Tomcat. O Serviço de Aplicativo já modifica esses arquivos para fornecer recursos de plataforma. Para continuar a usar esses recursos, é importante preservar o conteúdo desses arquivos quando você fizer alterações neles. Para fazê-lo, recomendamos que você use uma transformação XSL (XSLT). Use uma transformação XSL para fazer alterações nos arquivos XML enquanto preserva o conteúdo original do arquivo.

Exemplo de arquivo XSLT

Esta transformação de exemplo adiciona um novo nó de conector a server.xml. Observe a Transformação de identidade, que preserva o conteúdo original do arquivo.

    <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>
Função para transformação XSL

O PowerShell tem ferramentas internas para transformar arquivos XML usando as transformações XSL. O script a seguir é uma função de exemplo que você pode usar em startup.ps1 para realizar a transformação:

    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
    }
Configurações de aplicativo

A plataforma também precisa saber onde sua versão personalizada do Tomcat está instalada. Você pode definir o local da instalação na configuração de aplicativo CATALINA_BASE.

Você pode usar a CLI do Azure para alterar essa configuração:

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

Ou alterar manualmente a configuração no portal do Azure:

  1. Vá para Configurações>Definição>Configurações de aplicativo.
  2. Selecione Nova configuração de aplicativo.
  3. Use estes valores para criar a configuração:
    1. Nome: CATALINA_BASE
    2. Valor: "%LOCAL_EXPANDED%\tomcat"
Startup.ps1 de exemplo

O seguinte script de exemplo copia um Tomcat personalizado para uma pasta local, realiza uma transformação XSL e indica que a transformação foi bem-sucedida:

    # 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
    }

Finalizar a configuração

Por fim, coloque os JARs do driver no classpath do Tomcat e reinicie o Serviço de Aplicativo. Garanta que os arquivos do driver JDBC estão disponíveis para o carregador de classes do Tomcat colocando-os no diretório /home/site/lib. No Cloud Shell, execute az webapp deploy --type=lib para cada JAR de driver:

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

Tomcat

Essas instruções se aplicam a todas as conexões de banco de dados. Você precisa preencher os espaços reservados com nome de classe do driver do banco de dados escolhido e o arquivo JAR. É fornecida uma tabela com nomes de classe e downloads de driver para bancos de dados comuns.

Banco de dados Nome de Classe do Driver Driver JDBC
PostgreSQL org.postgresql.Driver Download
MySQL com.mysql.jdbc.Driver Baixar (Selecione "Independente de Plataforma")
SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver Download

Para configurar o Tomcat para usar a JDBC (Conectividade de Banco de Dados Java) ou a JPA (API de Persistência Java), primeiro personalize a variável de ambiente CATALINA_OPTS lida em Tomcat na inicialização do backup. Defina esses valores por meio de uma configuração de aplicativo no plug-in Maven do Serviço de Aplicativo:

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

Ou defina as variáveis de ambiente na página Configuração>Configurações de Aplicativo no portal do Azure.

Em seguida, determine se a fonte de dados deve estar disponível para um aplicativo ou para todos os aplicativos em execução no servlet do Tomcat.

Fontes de dados no nível do aplicativo

  1. Crie um arquivo context.xml no diretório META-INF/ do seu projeto. Crie o diretório META-INF/ se ele não existir.

  2. Em context.xml, adicione um elemento Context para vincular a fonte de dados a um endereço JNDI. Substitua o espaço reservado driverClassName pelo nome de classe do seu driver da tabela acima.

    <Context>
        <Resource
            name="jdbc/dbconnection"
            type="javax.sql.DataSource"
            url="${connURL}"
            driverClassName="<insert your driver class name>"
            username="${dbuser}"
            password="${dbpassword}"
        />
    </Context>
    
  3. Atualize o web.xml do aplicativo para usar a fonte de dados no aplicativo.

    <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 compartilhados no nível do servidor

A adição de uma fonte de dados compartilhada no nível do servidor exige a edição do server.xml do Tomcat. Primeiro, carregue um script de inicialização e defina o caminho para o script em Configuração>Comando de Inicialização. Você pode carregar o script de inicialização usando o FTP.

O script de inicialização fará uma transformação de xsl no arquivo server.xml e produzirá o arquivo xml resultante para /usr/local/tomcat/conf/server.xml. O script de inicialização deve instalar o libxslt via apk. O arquivo xsl e o script de inicialização podem ser carregados via FTP. Confira abaixo um exemplo de script de inicialização.

# 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

O arquivo XSL de exemplo a seguir adiciona um novo nó do conector ao server.xml do 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>

Finalizar a configuração

Por fim, coloque os JARs do driver no classpath do Tomcat e reinicie o Serviço de Aplicativo.

  1. Garanta que os arquivos do driver JDBC estão disponíveis para o carregador de classes do Tomcat colocando-os no diretório /home/site/lib. No Cloud Shell, execute az webapp deploy --type=lib para cada JAR de driver:
az webapp deploy --resource-group <group-name> --name <app-name> --src-path <jar-name>.jar --type=lib --path <jar-name>.jar

Se você tiver uma fonte de dados no nível do servidor, reinicie o aplicativo Linux Serviço de Aplicativo. O Tomcat redefinirá CATALINA_BASE como /home/tomcat e usará a configuração atualizada.

Fontes de dados JBoss EAP

Há três etapas principais ao registrar uma fonte de dados com o JBoss EAP: carregar o driver JDBC, adicionar o driver JDBC como módulo e registrar o módulo. O Serviço de Aplicativo é um serviço de hospedagem sem estado, portanto, os comandos de configuração para adicionar e registrar o módulo da fonte de dados devem ter um script e ser aplicados à medida que o contêiner é iniciado.

  1. Obtenha o driver JDBC do banco de dados.

  2. Crie um arquivo de definição do módulo XML para o driver JDBC. O exemplo a seguir mostra uma definição 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 os comandos da CLI do JBoss em um arquivo denominado jboss-cli-commands.cli. Os comandos do JBoss devem adicionar o módulo e registrá-lo como fonte de dados. O exemplo a seguir mostra os comandos da CLI do 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. Crie um script de inicialização startup_script.sh que chama os comandos da CLI do JBoss. O exemplo a seguir mostra como chamar seu jboss-cli-commands.cli. Posteriormente, você configurará o Serviço de Aplicativo para executar esse script quando o contêiner for iniciado.

    $JBOSS_HOME/bin/jboss-cli.sh --connect --file=/home/site/deployments/tools/jboss-cli-commands.cli
    
  5. Usando um cliente FTP de sua escolha, carregue o driver JDBC, jboss-cli-commands.cli, startup_script.sh e a definição do módulo para /site/deployments/tools/.

  6. Configure o site para executar startup_script.sh quando o contêiner for iniciado. No portal do Azure, navegue até Configuração>Configurações Gerais>Comando de Inicialização. Defina o campo de comando de inicialização como /home/site/deployments/tools/startup_script.sh. Salve suas alterações.

Para confirmar se a fonte de dados foi adicionada ao servidor do JBoss, use o SSH no aplicativo Web e execute $JBOSS_HOME/bin/jboss-cli.sh --connect. Quando você estiver conectado ao JBoss, execute o /subsystem=datasources:read-resource para imprimir uma lista das fontes de dados.

robots933456 em logs

Você poderá ver a seguinte mensagem nos logs de contêiner:

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

Você pode ignorar essa mensagem com segurança. /robots933456.txt é um caminho de URL fictício que o Serviço de Aplicativo usa para verificar se o contêiner é capaz de atender a solicitações. Uma resposta 404 indica apenas que o caminho não existe, mas informa ao Serviço de Aplicativo que o contêiner está íntegro e pronto para responder a solicitações.

Como escolher uma versão runtime Java

O Serviço de Aplicativo permite que os usuários escolham a versão principal da JVM, como Java 8 ou Java 11, e a versão do patch, como 1.8.0 _232 ou 11.0.5. Você também pode optar por atualizar a versão do patch automaticamente, à medida que novas versões secundárias se tornarem disponíveis. Na maioria dos casos, os sites de produção devem usar as versões da JVM de patch fixadas. Isso evita interrupções inesperadas durante a atualização automática de uma versão de patch. Todos os aplicativos Web Java usam JVMs de 64 bits e não são configuráveis.

Se você estiver usando o Tomcat, poderá optar por fixar a versão de patch do Tomcat. No Windows, você pode fixar as versões de patch da JVM e do Tomcat de maneira independente. No Linux, você pode fixar a versão de patch do Tomcat; a versão de patch da JVM também é fixada, mas não pode ser configurada separadamente.

Caso opte por fixar a versão secundária, será necessário atualizar periodicamente a versão secundária da JVM no aplicativo. Para garantir que o aplicativo seja executado na versão secundária mais recente, crie um slot de preparo e aumente a versão secundária no slot de preparo. Após confirmar se o aplicativo foi executado corretamente na nova versão secundária, você pode trocar os slots de preparo e de produção.

JBoss EAP

Clustering no JBoss EAP

O Serviço de Aplicativo dá suporte ao clustering para JBoss EAP versões 7.4.1 e superior. Para habilitar o clustering, seu aplicativo Web deve ser integrado a uma rede virtual. Quando o aplicativo Web é integrado a uma rede virtual, ele é reiniciado e a instalação do JBoss EAP é iniciada automaticamente com uma configuração clusterizado. As instâncias JBoss EAP se comunica pela sub-rede especificada na integração de rede virtual, usando as portas mostradas na variável de ambiente WEBSITES_PRIVATE_PORTS em runtime. Você pode desabilitar o clustering criando uma configuração de aplicativo chamada WEBSITE_DISABLE_CLUSTERING com qualquer valor.

Observação

Caso esteja habilitando a integração de rede virtual com um modelo do ARM, precisará definir manualmente a propriedade vnetPrivatePorts para um valor de 2. Caso habilite a integração de rede virtual da CLI ou do Portal, essa propriedade será definida para você automaticamente.

Quando o clustering está habilitado, as instâncias JBoss EAP usam o protocolo de descoberta JGroups do FILE_PING para descobrir novas instâncias e persistir as informações do cluster, como os membros do cluster, seus identificadores e seus endereços IP. No Serviço de Aplicativo, esses arquivos estão em /home/clusterinfo/. A primeira instância de EAP a iniciar obtém permissões de leitura/gravação no arquivo de associação de cluster. Outras instâncias fazem a leitura do arquivo, encontram o nó primário e coordenam com esse nó a ser incluído no cluster e adicionados ao arquivo.

Os tipos de Plano de Serviço de Aplicativo Premium V3 e V2 Isolado podem opcionalmente ser distribuídos entre Zonas de Disponibilidade para melhorar a resiliência e a confiabilidade de suas cargas de trabalho críticas para os negócios. Essa arquitetura também é conhecida como redundância de zona. O recurso de agrupamento do JBoss EAP tem suporte com o recurso de redundância de zona.

Regras de dimensionamento automático

Ao configurar regras de dimensionamento automático para dimensionamento horizontal, é importante remover instâncias incrementalmente (uma de cada vez) para garantir que cada instância removida transfira sua atividade (como manipular uma transação de banco de dados) a outro membro do cluster. Ao configurar as regras de dimensionamento automático no Portal para redução vertical, use as seguintes opções:

  • Operação: "Diminuir contagem em"
  • Esfriar: "5 minutos" ou mais
  • Contagem de instâncias: 1

Você não precisa adicionar instâncias incrementalmente (dimensionamento horizontal), basta adicionar várias instâncias ao cluster de cada vez.

Planos do Serviço de Aplicativo JBoss EAP

O JBoss EAP só está disponível nos tipos de Plano do Serviço de Aplicativo Premium v3 e v2 isolado. Os clientes que criaram um site do JBoss EAP em uma camada diferente durante a visualização pública devem escalar verticalmente para a camada de hardware Premium ou Isolado a fim de evitar um comportamento inesperado.

Configuração da linha de base do Tomcat nos Serviços de Aplicativos

Os desenvolvedores Java poderão personalizar as configurações do servidor, solucionar problemas e implantar aplicativos no Tomcat com confiança se souberem sobre o arquivo server.xml e os detalhes de configuração do Tomcat. As possíveis personalizações incluem:

  • Personalizar a configuração do Tomcat: ao entender o arquivo server.xml e os detalhes de configuração do Tomcat, você poderá ajustar as configurações do servidor para corresponder às necessidades de seus aplicativos.
  • Depuração: quando um aplicativo é implantado em um servidor Tomcat, os desenvolvedores precisam conhecer a configuração do servidor para depurar os problemas que possam surgir. Isso inclui verificar os logs do servidor, examinar os arquivos de configuração e identificar erros que possam estar ocorrendo.
  • Solucionar problemas do Tomcat: inevitavelmente, os desenvolvedores do Java encontram problemas com seu servidor Tomcat, como problemas de desempenho ou erros de configuração. Ao entender o arquivo server.xml e os detalhes de configuração do Tomcat, os desenvolvedores podem diagnosticar e solucionar esses problemas rapidamente, o que pode economizar tempo e esforço.
  • Implantar aplicativos no Tomcat: para implantar um aplicativo Web Java no Tomcat, os desenvolvedores precisam saber como configurar o arquivo server.xml e outras configurações do Tomcat. Entender esses detalhes é essencial para implantar aplicativos com êxito e garantir que eles sejam executados sem problemas no servidor.

Ao criar um aplicativo com o Tomcat integrado para hospedar a carga de trabalho do Java (um arquivo WAR ou um arquivo JAR), há determinadas configurações que você obtém prontas para uso para a configuração do Tomcat. Você pode consultar a Documentação Oficial do Apache Tomcat para obter informações detalhadas, incluindo a configuração padrão do Servidor Web Tomcat.

Além disso, há certas transformações que são aplicadas ainda mais sobre o server.xml para a distribuição do Tomcat no início. Essas são transformações para as configurações de conector, host e válvula.

Observe que as versões mais recentes do Tomcat têm server.xml (8.5.58 e 9.0.38 em diante). As versões mais antigas do Tomcat não usam transformações e podem ter um comportamento diferente como resultado.

Connector

<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 está definido como 16384
  • URIEncoding está definido como UTF-8
  • conectionTimeout é definido como WEBSITE_TOMCAT_CONNECTION_TIMEOUT, que usa 240000 como padrão
  • maxThreads é definido como WEBSITE_CATALINA_MAXTHREADS, que usa 200 como padrão
  • maxConnections é definido como WEBSITE_CATALINA_MAXCONNECTIONS, que usa 10000 como padrão

Observação

As configurações connectionTimeout, maxThreads e maxConnections podem ser ajustadas com as configurações do aplicativo

A seguir estão exemplos de comandos da CLI que poderá usar para alterar os valores de conectionTimeout, maxThreads ou 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
  • O conector usa o endereço do contêiner em vez 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 é definido como AZURE_SITE_APP_BASE, que usa WebappsLocalPath local como padrão
  • xmlBase é definido como AZURE_SITE_HOME, que usa /site/wwwroot como padrão
  • unpackWARs é definido como AZURE_UNPACK_WARS, que usa true como padrão
  • workDir é definido como JAVA_TMP_DIR, que usa TMP como padrão
  • errorReportValveClass usa nossa válvula de relatório de erros 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 é definido como AZURE_LOGGING_DIR, que usa home\logFiles como padrão
  • maxDays é WEBSITE_HTTPLOGGING_RETENTION_DAYS, que usa 0 como padrão [para sempre]

No Linux, ele tem toda a mesma personalização, além de:

  • Adiciona algumas páginas de erro e relatório à 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>

Próximas etapas

Acesse a central para Desenvolvedores do Azure para Java para conferir inícios rápidos, tutoriais e documentação de referência do Java.