Migrar aplicativos Tomcat para Aplicativos de Contêiner do Azure
Este guia descreve o que você deve estar ciente quando deseja migrar um aplicativo Tomcat existente para ser executado em Aplicativos de Contêiner do Azure (ACA).
Pré-migração
Para garantir uma migração bem-sucedida, antes de começar, conclua as etapas de avaliação e inventário descritas nas seções a seguir.
Inventariar os recursos externos
Os recursos externos, como origens de dados, mediadores de mensagens JMS, entre outros, são injetados através de Java Naming and Directory Interface (JNDI). Alguns desses recursos podem precisar de migração ou reconfiguração.
Na aplicação
Inspecione o ficheiro META-INF/context.xml. Procure elementos <Resource>
dentro do elemento <Context>
.
No servidor ou servidores da aplicação
Inspecione os ficheiros $CATALINA_BASE/conf/context.xml e $CATALINA_BASE/conf/server.xml, bem como os ficheiros .xml e localizados nos diretórios $CATALINA_BASE/conf/[engine-name]/[host-name].
Nos ficheiros context.xml, os recursos JNDI serão descritos pelos elementos <Resource>
dentro do elemento <Context>
de nível superior.
Nos ficheiros server.xml, os recursos JNDI serão descritos pelos elementos <Resource>
dentro do elemento <GlobalNamingResources>
.
Origens de Dados
Origens de dados e recursos JNDI com o atributo type
definido como javax.sql.DataSource
. Documente a seguinte informação de cada origem de dados:
- Qual é o nome da origem de dados?
- Qual é a configuração do conjunto de ligações?
- Onde posso obter o ficheiro JAR do controlador JDBC?
Para obter mais informações, veja o MANUAL DE INSTRUÇÕES da Origem de Dados do JNDI na documentação do Tomcat.
Todos os outros recursos externos
Não é exequível documentar todas as dependências externas possíveis neste guia. Cabe à sua equipa verificar que pode satisfazer todas as dependências externas da sua aplicação após a migração.
Inventariar segredos
Palavras-passe e cadeias protegidas
Procure cadeias de segredos e palavras-passe nas propriedades e nos ficheiros de configuração do servidor ou servidores de produção. Não se esqueça de verificar server.xml e context.xml em $CATALINA_BASE/conf. Também poderá encontrar ficheiros de configuração com palavras-passe ou credenciais dentro da aplicação. Esses ficheiros podem incluir META-INF/context.xml e, para aplicações Spring Boot, application.properties ou application.yml.
Determinar se e como é que o sistema de ficheiros é utilizado
Qualquer utilização do sistema de ficheiros no servidor de aplicações irá exigir uma reconfiguração ou, em casos raros, alterações da arquitetura. Poderá identificar alguns ou todos os cenários seguintes.
Conteúdo estático só de leitura
Se a sua aplicação servir conteúdo estático atualmente, precisa de uma localização alternativa para o mesmo. Pode considerar mover o conteúdo estático para o Armazenamento de Blobs do Azure e adicionar a CDN do Azure para obter transferências super-rápidas a nível global. Para obter mais informações, consulte Hospedagem de site estático no Armazenamento do Azure e Guia de início rápido: integrar uma conta de armazenamento do Azure com a CDN do Azure.
Conteúdo estático publicado dinamicamente
Se a sua aplicação permitir conteúdo estático carregado/produzido pela mesma, mas que é imutável após a criação, pode utilizar o Armazenamento de Blobs do Azure e a CDN do Azure conforme descrito acima, com uma função das Funções do Azure que lide com os carregamentos e as atualizações da CDN. Disponibilizamos uma implementação de exemplo que pode utilizar, em Uploading and CDN-preloading static content with Azure Functions (Carregamento e pré-carregamento da CDN de conteúdo estático com as Funções do Azure).
Identificar o mecanismo de persistência de sessão
Para identificar o gestor de persistência de sessão que está a ser utilizado, inspecione os ficheiros context.xml que se encontram na sua aplicação e a configuração do Tomcat. Procure o elemento <Manager>
e, em seguida, veja o valor do atributo className
.
As implementações integradas do Tomcat PersistentManager, como StandardManager ou FileStore, não foram projetadas para uso com uma plataforma distribuída e dimensionada, como o ACA. O ACA pode balancear a carga entre várias instâncias e reiniciar qualquer instância de forma transparente a qualquer momento, portanto, não é recomendável persistir o estado mutável em um sistema de arquivos.
Se a persistência da sessão for necessária, você precisará usar uma implementação alternativa PersistentManager
que gravará em um armazenamento de dados externo, como o VMware Tanzu Session Manager com Cache Redis.
Casos especiais
Certos cenários de produção podem exigir mais alterações ou impor mais limitações. Embora esses cenários possam ser pouco frequentes, é importante garantir que eles sejam inaplicáveis ao seu aplicativo ou resolvidos corretamente.
Determinar se a aplicação depende de tarefas agendadas
As tarefas agendadas, tais como tarefas do Quartz Scheduler ou do Cron, não podem ser utilizadas com implementações Tomcat em contentor. Se a sua aplicação estiver ampliada, uma tarefa agendada pode ser executada mais de uma vez por período agendado. Esta situação pode provocar consequências não intencionais.
Faça o inventário de todas as tarefas agendadas, dentro ou fora do servidor de aplicações.
Determinar se a aplicação contem código de SO específico
Se seu aplicativo contiver qualquer código com dependências no sistema operacional 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 por File.Separator
ou Paths.get
se seu aplicativo estiver sendo executado no Windows.
Determinar se o MemoryRealm está a ser utilizado
O MemoryRealm necessita de um ficheiro XML persistente. No ACA, você precisará adicionar esse arquivo à imagem do contêiner ou carregá-lo para o armazenamento compartilhado disponibilizado para contêineres. (Para mais informações, consulte o Identificar a seção do mecanismo de persistência da sessão.) O pathName
parâmetro terá de ser modificado em conformidade.
Para determinar se o MemoryRealm
está a ser utilizado atualmente, inspecione os seus ficheiros server.xml e context.xml e procure elementos <Realm>
nos quais o atributo className
está definido como org.apache.catalina.realm.MemoryRealm
.
Testes no local
Antes de criar imagens de contêiner, migre seu aplicativo para o JDK e o Tomcat que você pretende usar no ACA. Teste a sua aplicação de forma minuciosa para garantir a compatibilidade e o desempenho.
Parametrizar a configuração
É provável que na fase de pré-migração tenha identificado segredos e dependências externas, tais como origens de dados, nos ficheiros server.xml e context.xml. Para cada item identificado como tal, substitua todos os nomes de utilizador, palavras-passe, cadeias de ligação ou URLs por uma variável de ambiente.
Nota
A Microsoft recomenda o uso do fluxo de autenticação mais seguro disponível. O fluxo de autenticação descrito neste procedimento, como para bancos de dados, caches, mensagens ou serviços de IA, requer um grau muito alto de confiança no aplicativo e traz riscos não presentes em outros fluxos. Use esse fluxo somente quando opções mais seguras, como identidades gerenciadas para conexões sem senha ou sem chave, não forem viáveis. Para operações de máquina local, prefira identidades de usuário para conexões sem senha ou sem chave.
Por exemplo, imagine que o ficheiro 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="{password}"
/>
Neste caso, pode mudá-lo conforme mostrado no seguinte exemplo:
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="${postgresdb.connectionString}"
driverClassName="org.postgresql.Driver"
username="${postgresdb.username}"
password="${postgresdb.password}"
/>
Migração
Nota
Algumas implementações do Tomcat poderão ter múltiplas aplicações em execução num único servidor Tomcat. Se for este o caso na sua implementação, recomendamos vivamente que execute cada aplicação num pod separado. Isto permite-lhe otimizar a utilização de recursos para cada aplicação e, ao mesmo tempo, minimizar a complexidade e o acoplamento.
Preparar os artefactos de implementação
Clone o repositório Tomcat on Containers Quickstart GitHub. Este repositório contém um Dockerfile e arquivos de configuração 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 implantar no ACA.
Adicionar recursos 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:
Nota
A Microsoft recomenda o uso do fluxo de autenticação mais seguro disponível. O fluxo de autenticação descrito neste procedimento, como para bancos de dados, caches, mensagens ou serviços de IA, requer um grau muito alto de confiança no aplicativo e traz riscos não presentes em outros fluxos. Use esse fluxo somente quando opções mais seguras, como identidades gerenciadas para conexões sem senha ou sem chave, não forem viáveis. Para operações de máquina local, prefira identidades de usuário para conexões sem senha ou sem chave.
<!-- 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 origem de dados, veja as seguintes secções do Manual de Instruções da Origem de Dados do JNDI na documentação do Tomcat:
Criar e emitir a imagem
A maneira mais simples de criar e carregar a imagem no Azure Container Registry (ACR) para uso pelo ACA é usar o az acr build
comando. Este comando não exige que o Docker esteja instalado no teu 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 do 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 .
Pode omitir o parâmetro --build-arg APP_FILE...
se o seu ficheiro WAR se chamar ROOT.war. Pode omitir o parâmetro --build-arg SERVER_XML...
se o seu ficheiro XML de servidor se chamar server.xml. Estes dois ficheiros têm de estar no mesmo diretório do Dockerfile.
Como alternativa, você pode usar a CLI do Docker para criar a imagem localmente usando os comandos a seguir. Esta abordagem pode simplificar os testes e refinar a imagem antes da implementação inicial no ACR. No entanto, exige que a CLI do Docker esteja 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, consulte Criar e armazenar imagens de contêiner com o Registro de Contêiner do Azure.
Implantar em 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, consulte Guia de início rápido: implantar seu primeiro aplicativo de contêiner.
Pós-migração
Agora que você migrou seu aplicativo para o ACA, verifique se ele funciona como esperado. Posto isto, temos algumas recomendações que podem tornar a sua aplicação mais nativa da nuvem.
Recomendações
Crie e implemente uma estratégia de continuidade de negócio e recuperação após desastre. Caso a aplicação seja crítica para a missão, considere uma arquitetura de implementação multirregiões. Para obter mais informações, consulte Práticas recomendadas para continuidade de negócios e recuperação de desastres no Serviço Kubernetes do Azure (AKS).
Avalie os itens que se encontram no ficheiro logging.properties. Considere eliminar ou reduzir parte das saídas de registo para melhorar o desempenho.
Considere monitorar o tamanho do cache de código e adicionar os parâmetros
-XX:InitialCodeCacheSize
e-XX:ReservedCodeCacheSize
aJAVA_OPTS
variável no Dockerfile para otimizar ainda mais o desempenho. Para obter mais informações, veja Codecache Tuning (Otimização de Codecache), na documentação da Oracle.Considere adicionar regras de alerta e grupos de ação do Azure Monitor para detetar e resolver rapidamente condições aberrantes.
Considere replicar a implantação dos Aplicativos de Contêiner do Azure em outra região para obter menor latência e maior confiabilidade e tolerância a falhas. Use o Gerenciador de Tráfego do Azure para balancear a carga entre implantações ou use o Azure Front Door para adicionar descarregamento SSL e Firewall de 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 descarregamento SSL e Firewall de Aplicativo Web com proteção contra DDoS.