Migrar aplicativos Tomcat para Aplicativos de Contêiner do Azure
Este guia descreve o que você deve saber quando deseja migrar um aplicativo Tomcat existente para executar em Aplicativos de Contêiner do Azure (ACA).
Pré-migração
Antes de tudo, para garantir uma migração bem-sucedida, conclua as etapas de avaliação e de inventário descritas nas seções a seguir.
Recursos externos de inventário
Recursos externos, como fontes de dados, agentes de mensagem JMS e outros, são injetados por meio de JNDI (Interface de Nomenclatura e Diretório do Java). Alguns desses recursos podem exigir migração ou reconfiguração.
Dentro de seu aplicativo
Inspecione o arquivo META-INF/context.xml. Procure elementos de <Resource>
dentro do elemento <Context>
.
Nos servidores de aplicativos
Inspecione os arquivos $CATALINA_BASE/conf/context.xml e $CATALINA_BASE/conf/server.xml, bem como os arquivos .xml encontrados nos diretórios $CATALINA_BASE/conf/[nome-do-mecanismo]/[nome-do-host].
Em arquivos context.xml, os recursos de JNDI serão descritos pelos elementos <Resource>
dentro do elemento <Context>
de nível superior.
Em arquivos server.xml, os recursos de JNDI serão descritos pelos elementos <Resource>
dentro do elemento <GlobalNamingResources>
.
Fontes de dados
Fontes de dados são recursos de JNDI com o atributo type
definido como javax.sql.DataSource
. Para cada fonte de dados, documente as seguintes informações:
- Qual é o nome da fonte de dados?
- Qual é a configuração do pool de conexões?
- Onde posso encontrar o arquivo JAR do driver JDBC?
Para obter mais informações, consulte Instruções de fonte de dados JNDI na documentação do Tomcat.
Todos os outros recursos externos
Não é possível documentar todas as dependências externas possíveis neste guia. É responsabilidade da sua equipe verificar se você pode atender a todas as dependências externas de seu aplicativo após a migração.
Segredos de inventário
Senhas e cadeias de caracteres seguras
Verifique todas as propriedades e os arquivos de configuração nos servidores de produção para quaisquer senhas e cadeias de caracteres secretas. É necessário verificar server.xml e context.xml em $CATALINA_BASE/conf. Você também pode encontrar arquivos de configuração que contenham senhas ou credenciais dentro de seu aplicativo. Eles podem incluir META-INF/context.xml e, para aplicativos Spring boot, arquivos application.properties ou application.yml.
Determinar se e como o sistema de arquivos é usado
Qualquer uso do sistema de arquivos no servidor de aplicativos exigirá reconfiguração ou, em casos raros, alterações de arquitetura. Você pode identificar alguns ou todos os cenários a seguir.
Conteúdo estático somente leitura
Se seu aplicativo estiver servindo conteúdo estático no momento, você precisará de um local alternativo para ele. Talvez você queira considerar a migração de conteúdo estático para o Armazenamento de Blobs do Azure e a adição da CDN do Azure para downloads extremamente rápidos, globalmente. Para obter mais informações, confira Hospedagem de site estático no Armazenamento do Microsoft Azure e Início rápido: Integrar uma conta de armazenamento do Azure à CDN do Azure.
Conteúdo estático publicado dinamicamente
Se o aplicativo permitir conteúdo estático que é carregado/produzido pelo aplicativo, mas não puder ser alterado após sua criação, você poderá usar o Armazenamento de Blobs do Azure e a CDN do Azure, conforme descrito acima, com uma Função do Azure para lidar com uploads e atualização de CDN. Fornecemos uma implementação de exemplo para seu uso em Carregar conteúdo estático e fazer o pré-carregamento desse conteúdo pela CDN com o Azure Functions.
Identificar o mecanismo de persistência da sessão
Para identificar o gerenciador de persistência de sessão em uso, inspecione os arquivos context.xml em seu aplicativo e a configuração do Tomcat. Procure o elemento <Manager>
e observe o valor do atributo className
.
As implementações internas de PersistentManager do Tomcat, como StandardManager ou FileStore, não são projetadas para uso com uma plataforma distribuída e dimensionada, como ACA. O ACA pode balancear a carga entre várias instâncias e reiniciar de forma transparente qualquer instância a qualquer momento, portanto a persistência de um estado mutável para um sistema de arquivos não é recomendada.
Se a persistência da sessão for necessária, você precisará usar uma implementação alternativa de PersistentManager
que será gravada em um armazenamento de dados externo, como o VMware Tanzu Session Manager com o Cache Redis.
Casos especiais
Determinados cenários de produção podem exigir mais alterações ou impor mais limitações. Embora esses cenários sejam raros, é importante verificar se eles não se aplicam ao aplicativo ou estão resolvidos corretamente.
Determinar se o aplicativo depende de trabalhos agendados
Trabalhos agendados, como tarefas do Agendador do Quartz ou trabalhos cron, não podem ser usados com implantações do Tomcat em contêineres. Se o aplicativo for escalado horizontalmente, um trabalho agendado poderá ser executado mais de uma vez por período agendado. Essa situação pode levar a consequências indesejadas.
Inventarie quaisquer trabalhos agendados, dentro ou fora do servidor de aplicativos.
Determinar se o aplicativo contém código específico do sistema operacional
Se seu aplicativo contiver qualquer código com dependências do sistema operacional do host, você precisará refatorá-lo para remover essas dependências. Por exemplo, talvez seja necessário substituir qualquer uso de /
ou \
em caminhos do sistema de arquivos com File.Separator
ou Paths.get
se o aplicativo estiver em execução no Windows.
Determinar se MemoryRealm é usado
MemoryRealm requer um arquivo XML persistente. No ACA, você precisará adicionar esse arquivo à imagem de contêiner ou carregá-lo no armazenamento compartilhado disponibilizado para os contêineres. (Para obter mais informações, confira a seção Identificar o mecanismo de persistência da sessão.) O parâmetro pathName
terá que ser modificado de acordo.
Para determinar se MemoryRealm
está sendo usado no momento, inspecione os arquivos server.xml e context.xml e pesquise por elementos <Realm>
em que o atributo className
está definido como org.apache.catalina.realm.MemoryRealm
.
Teste in-loco
Antes de criar imagens de contêiner, migre seu aplicativo para o JDK e o Tomcat que você pretende usar no ACA. Teste seu aplicativo cuidadosamente para garantir a compatibilidade e o desempenho.
Parametrizar a configuração
Na pré-migração, você provavelmente terá identificado segredos e dependências externas, como fontes de dados, nos arquivos server.xml e context.xml. Para cada item identificado assim, substitua qualquer nome de usuário, senha, cadeia de conexão ou URL por uma variável de ambiente.
Por exemplo, suponha que o arquivo context.xml contém o seguinte elemento:
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="jdbc:postgresql://postgresdb.contoso.com/wickedsecret?ssl=true"
driverClassName="org.postgresql.Driver"
username="postgres"
password="t00secure2gue$$"
/>
Nesse caso, você poderia alterá-lo conforme mostrado no exemplo a seguir:
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="${postgresdb.connectionString}"
driverClassName="org.postgresql.Driver"
username="${postgresdb.username}"
password="${postgresdb.password}"
/>
Migração
Observação
Algumas implantações do Tomcat podem ter vários aplicativos em execução em um único servidor Tomcat. Se esse for o caso em sua implantação, será altamente recomendável executar cada aplicativo em um pod separado. Isso permite que você otimize a utilização de recursos para cada aplicativo, minimizando a complexidade e o acoplamento.
Preparar os artefatos de implantação
Clone o repositório GitHub do Início Rápido do Tomcat em contêineres. Esse repositório contém um Dockerfile e arquivos de configuração do Tomcat com muitas otimizações recomendadas. Nas etapas abaixo, descrevemos as modificações que você provavelmente precisará fazer nesses arquivos antes de criar a imagem de contêiner e implantá-la no ACA.
Adicionar recursos de JNDI
Edite server.xml para adicionar os recursos que você preparou nas etapas de pré-migração, como fontes de dados, conforme mostrado no exemplo a seguir:
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml"
/>
<!-- Migrated datasources here: -->
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="${postgresdb.connectionString}"
driverClassName="org.postgresql.Driver"
username="${postgresdb.username}"
password="${postgresdb.password}"
/>
<!-- End of migrated datasources -->
</GlobalNamingResources>
Para obter instruções adicionais da fonte de dados, consulte as seções a seguir das Instruções de fonte de dados JNDI na documentação do Tomcat:
Criar imagem e enviá-la por push
A maneira mais simples de criar a imagem e carregá-la no ACR (Registro de Contêiner do Azure) para uso pelo ACA é usar o comando az acr build
. Este comando não requer que o Docker seja instalado no seu computador. Por exemplo, se você tiver o Dockerfile do repositório tomcat-container-quickstart e o pacote de aplicativos petclinic.war no diretório atual, poderá criar a imagem de contêiner no ACR com o seguinte comando:
az acr build \
--registry $acrName \
--image "${acrName}.azurecr.io/petclinic:{{.Run.ID}}"
--build-arg APP_FILE=petclinic.war \
--build-arg SERVER_XML=prod.server.xml .
Você poderá omitir o parâmetro --build-arg APP_FILE...
se o seu arquivo WAR for nomeado ROOT.war. Você poderá omitir o parâmetro --build-arg SERVER_XML...
se o seu arquivo XML do servidor for nomeado server.xml. Ambos os arquivos precisam estar no mesmo diretório que o Dockerfile.
Como alternativa, você pode usar a CLI do Docker para compilar a imagem localmente usando os comandos a seguir. Essa abordagem pode simplificar o teste e refinar a imagem antes da implantação inicial no ACR. No entanto, ela requer que a CLI do Docker seja instalada e que o daemon do Docker esteja em execução.
# Build the image locally.
sudo docker build . --build-arg APP_FILE=petclinic.war -t "${acrName}.azurecr.io/petclinic:1"
# Run the image locally.
sudo docker run -d -p 8080:8080 "${acrName}.azurecr.io/petclinic:1"
# You can now access your application with a browser at http://localhost:8080.
# Sign in to ACR.
sudo az acr login --name $acrName
# Push the image to ACR.
sudo docker push "${acrName}.azurecr.io/petclinic:1"
Para obter mais informações, confira Criar e armazenar imagens de contêiner com o Registro de Contêiner do Azure.
Implantar nos Aplicativos de Contêiner do Azure
O comando a seguir mostra um exemplo de implantação:
az containerapp create \
--resource-group <RESOURCE_GROUP> \
--name <APP_NAME> \
--environment <ENVIRONMENT_NAME> \
--image <IMAGE_NAME> \
--target-port 8080 \
--ingress 'external' \
--registry-server <REGISTRY_SERVER> \
--min-replicas 1
Para obter um início rápido mais detalhado, confira Início Rápido: Implantar o seu primeiro aplicativo de contêiner.
Após a migração
Agora que você migrou seu aplicativo para o ACA, você deve verificar se ele funciona conforme o esperado. Depois de fazer isso, temos algumas recomendações para você que podem tornar seu aplicativo mais nativo da nuvem.
Recomendações
Criar a implementar uma estratégia de continuidade dos negócios e recuperação de desastre. Para aplicativos críticos, considere a possibilidade de usar uma arquitetura de implantação em várias regiões. Para mais informações, confira Práticas recomendadas para continuidade dos negócios e recuperação de desastres no AKS (Serviço de Kubernetes do Azure).
Avalie os itens no arquivo logging.properties. Considere a possibilidade de eliminar ou reduzir parte da saída de log para melhorar o desempenho.
Considere a possibilidade de monitorar o tamanho do cache de código e de adicionar os parâmetros
-XX:InitialCodeCacheSize
e-XX:ReservedCodeCacheSize
à variávelJAVA_OPTS
no Dockerfile para otimizar ainda mais o desempenho. Para obter mais informações, confira Ajuste do Codecache na documentação Oracle.Considere adicionar as regras de alerta e os grupos de ações do Azure Monitor para detectar e abordar as condições anormais rapidamente.
Considere replicar a implantação dos Aplicativos de Contêiner do Azure em outra região para obter latência mais baixa, maior confiabilidade e tolerância a falhas. Use o Gerenciador de Tráfego do Azure para balancear a carga entre implantações ou o Azure Front Door para adicionar o descarregamento de SSL e o firewall do aplicativo Web com proteção contra DDoS.
Se a replicação geográfica não for necessária, considere adicionar um Gateway de Aplicativo do Azure para adicionar o descarregamento de SSL e o Firewall do aplicativo Web com proteção contra DDoS.