Eseguire la migrazione di applicazioni Tomcat a Tomcat nel servizio app di Azure

Questa guida descrive gli aspetti da considerare per la migrazione di un'applicazione Tomcat esistente da eseguire nel servizio app di Azure con Tomcat 9.0.

Pre-migrazione

Per garantire una corretta migrazione, prima di iniziare completare i passaggi di valutazione e inventario descritti nelle sezioni seguenti.

Se non è possibile soddisfare i requisiti di pre-migrazione, vedere le guide alla migrazione complementari seguenti:

Passare a una piattaforma supportata

Il servizio app offre versioni specifiche di Tomcat per versioni specifiche di Java. Per garantire la compatibilità, eseguire la migrazione dell'applicazione a una delle versioni supportate di Tomcat e Java nell'ambiente corrente prima di procedere con i passaggi rimanenti. Assicurarsi di testare completamente la configurazione risultante. Usare la versione stabile più recente della distribuzione Linux in questi test.

Nota

Questa convalida è particolarmente importante se il server corrente è in esecuzione in un JDK non supportato, ad esempio Oracle JDK o IBM OpenJ9.

Per ottenere la versione corrente di Java, accedere al server di produzione ed eseguire il comando seguente:

java -version

Nel servizio app Azure i file binari per Java 8 vengono forniti da Eclipse Temtalk. Per Java 11, 17 e tutte le future versioni LTS di Java, servizio app fornisce Microsoft Build of OpenJDK. Questi file binari sono disponibili gratuitamente per il download nei siti seguenti:

Per ottenere la versione corrente di Java, accedere al server di produzione ed eseguire il comando seguente:

${CATALINA_HOME}/bin/version.sh

Per ottenere la versione corrente usata dal servizio app di Azure, scaricare Tomcat 9, a seconda della versione che si intende usare nel servizio app di Azure.

Inventario delle risorse esterne

Le risorse esterne, ad esempio le origini dati, i broker di messaggi JMS e altre, vengono inserite tramite JNDI (Java Naming and Directory Interface). Alcune di queste risorse possono richiedere la migrazione o la riconfigurazione.

All'interno dell'applicazione

Esaminare il file META-INF/context.xml. Cercare gli elementi <Resource> all'interno dell'elemento <Context>.

Nei server applicazioni

Esaminare i file $CATALINA_BASE/conf/context.xml e $CATALINA_BASE/conf/server.xml, oltre ai file con estensione xml disponibili nelle directory $CATALINA_BASE/conf/[nome-motore]/[nome-host].

Nei file context.xml le risorse JNDI verranno descritte dagli elementi <Resource> all'interno dell'elemento <Context> di primo livello.

Nei file server.xml le risorse JNDI verranno descritte dagli elementi <Resource> all'interno dell'elemento <GlobalNamingResources>.

Datasources

Le origini dati sono risorse JNDI con l'attributo type impostato su javax.sql.DataSource. Per ogni origine dati, documentare le informazioni seguenti:

  • Qual è il nome dell'origine dati?
  • Qual è la configurazione del pool di connessioni?
  • Dove è possibile trovare il file JAR del driver JDBC?

Per altre informazioni, vedere la sezione di procedure per le origini dati JNDI nella documentazione di Tomcat.

Tutte le altre risorse esterne

Non è possibile documentare tutte le possibili dipendenze esterne in questa guida. È responsabilità del team verificare che sia possibile soddisfare tutte le dipendenze esterne dell'applicazione dopo la migrazione.

Inventario dei segreti

Password e stringhe sicure

Controllare tutte le proprietà e i file di configurazione nei server di produzione per verificare la presenza di stringhe segrete e password. Assicurarsi di controllare i file server.xml e context.xml in $CATALINA_BASE/conf. È anche possibile trovare i file di configurazione contenenti password o credenziali all'interno dell'applicazione. Possono includere il file META-INF/context.xml e, per le applicazioni Spring Boot, il file application.properties o application.yml.

Inventario dei certificati

Documentare tutti i certificati usati per gli endpoint SSL pubblici o per la comunicazione con i database back-end e altri sistemi. È possibile visualizzare tutti i certificati nei server di produzione eseguendo il comando seguente:

keytool -list -v -keystore <path to keystore>

Determinare se e come viene usato il file system

Qualsiasi utilizzo del file system nel server applicazioni richiede modifiche della configurazione o, in casi rari, dell'architettura. È possibile identificare alcuni o tutti gli scenari seguenti.

Contenuto statico di sola lettura

Se l'applicazione attualmente distribuisce contenuto statico, è necessario modificarne la posizione. Si può scegliere di spostare il contenuto statico in Archiviazione BLOB di Azure e di aggiungere la rete di distribuzione dei contenuti di Azure per accelerare i download a livello globale. Per altre informazioni, vedere Hosting di siti Web statici in Archiviazione di Azure e Avvio rapido: Integrare un account di archiviazione di Azure con Rete CDN di Azure. È anche possibile distribuire direttamente il contenuto statico in un'app nel piano Azure Spring Apps Enterprise. Per altre informazioni, vedere Distribuire file statici Web.

Contenuto statico pubblicato dinamicamente

Se l'applicazione consente contenuto statico caricato/prodotto dall'applicazione ma non modificabile dopo la creazione, è possibile usare Archiviazione BLOB di Azure e la rete di distribuzione dei contenuti di Azure, come descritto sopra, con una funzione di Azure per gestire i caricamenti e l'aggiornamento della rete CDN. Nell'articolo Caricamento e precaricamento nella rete CDN di contenuto statico con Funzioni di Azure è riportata un'implementazione di esempio che è possibile usare. È anche possibile distribuire direttamente il contenuto statico in un'app nel piano Azure Spring Apps Enterprise. Per altre informazioni, vedere Distribuire file statici Web.

Contenuto dinamico o interno

Per i file scritti e letti di frequente dall'applicazione, ad esempio i file di dati temporanei, o i file statici visibili solo all'applicazione, è possibile montare Archiviazione di Azure nel file system del servizio app. Per altre informazioni, vedere Rendere disponibile contenuto di Archiviazione di Azure nel servizio app in Linux.

Identificare il meccanismo di persistenza delle sessioni

Per identificare il gestore di persistenza delle sessioni in uso, esaminare i file context.xml nell'applicazione e nella configurazione di Tomcat. Cercare l'elemento <Manager>, quindi prendere nota del valore dell'attributo className.

Le implementazioni predefinite di PersistentManager di Tomcat, ad esempio StandardManager o FileStore, non sono progettate per l'uso con una piattaforma distribuita e scalabile come il servizio app. Poiché il servizio app può bilanciare il carico tra diverse istanze e riavviare in modo trasparente qualsiasi istanza in qualsiasi momento, non è consigliabile rendere persistente lo stato modificabile di un file system.

Se è richiesta la persistenza delle sessioni, è necessario usare un'implementazione di PersistentManager alternativa che scriverà in un archivio dati esterno, ad esempio VMware Tanzu Session Manager con Cache Redis. Per altre informazioni, vedere Usare Redis come cache di sessione con Tomcat.

Identificare tutti i processi e daemon esterni in esecuzione nei server di produzione

Se sono in esecuzione processi all'esterno del server applicazioni, ad esempio daemon di monitoraggio, sarà necessario eliminarli o trasferirli altrove.

Casi speciali

Alcuni scenari di produzione possono richiedere ulteriori modifiche o imporre limitazioni aggiuntive. Sebbene tali scenari siano poco frequenti, è importante assicurarsi che siano inapplicabili all'applicazione o risolti correttamente.

Determinare se l'applicazione si basa su processi pianificati

I processi pianificati, ad esempio le attività dell'utilità di Quartz Scheduler o i processi Cron, non possono essere usati con il servizio app. Il servizio app non impedisce la distribuzione interna di un'applicazione contenente attività pianificate. Tuttavia, se l'applicazione viene ampliata, lo stesso processo pianificato può essere eseguito più di una volta per ogni periodo pianificato. Questa situazione può provocare conseguenze indesiderate.

Creare un inventario di tutti i processi pianificati, all'interno o all'esterno del server applicazioni.

Determinare se l'applicazione contiene codice specifico del sistema operativo

Se l'applicazione contiene codice con dipendenze dal sistema operativo host, sarà necessario effettuarne il refactoring per rimuovere tali dipendenze. Ad esempio, potrebbe essere necessario sostituire qualsiasi utilizzo di / o \ nei percorsi del file system con File.Separator o Paths.get.

Determinare se viene usato il clustering Tomcat

Il clustering Tomcat non è supportato nel servizio app di Azure. È invece possibile configurare e gestire il ridimensionamento e il bilanciamento del carico tramite il servizio app di Azure senza funzionalità specifiche di Tomcat. È possibile salvare in modo permanente lo stato della sessione in un percorso alternativo per renderlo disponibile tra le repliche. Per altre informazioni, vedere Identificare il meccanismo di persistenza delle sessioni.

Per determinare se l'applicazione usa il clustering, cercare l'elemento <Cluster> all'interno degli elementi <Host> o <Engine> nel file server.xml.

Determinare se vengono usati i connettori non HTTP

Il servizio app supporta solo un singolo connettore HTTP. Se l'applicazione richiede connettori aggiuntivi, ad esempio il connettore AJP, non usare il servizio app.

Per identificare i connettori HTTP usati dall'applicazione, cercare gli elementi <Connector> all'interno del file server.xml nella configurazione di Tomcat.

Determinare se viene usato MemoryRealm

MemoryRealm richiede un file XML persistente. Nel servizio app di Azure sarà necessario caricare questo file nella directory /home o in una delle relative sottodirectory oppure in una risorsa di archiviazione montata. Sarà quindi necessario modificare il parametro pathName di conseguenza.

Per determinare se MemoryRealm è attualmente in uso, esaminare i file server.xml e context.xml e cercare gli elementi <Realm> in cui l'attributo className è impostato su org.apache.catalina.realm.MemoryRealm.

Determinare se viene usato il monitoraggio delle sessioni SSL

Il servizio app esegue l'offload della sessione all'esterno del runtime di Tomcat, di conseguenza non è possibile usare il monitoraggio della sessione SSL. Usare invece una modalità di monitoraggio delle sessioni diversa (COOKIE o URL). Se il monitoraggio delle sessioni SSL è necessario, non usare il servizio app.

Determinare se viene usato AccessLogValve

Se si usa AccessLogValve, è necessario impostare il parametro directory su /home/LogFiles o su una delle relative sottodirectory.

Migrazione

Parametrizzare la configurazione

Nei passaggi di pre-migrazione è probabile che nei file server.xml e context.xml siano stati identificati alcuni segreti e dipendenze esterne, ad esempio origini dati. Per ogni elemento di questo tipo identificato, sostituire l'eventuale nome utente, password, stringa di connessione o URL con una variabile di ambiente.

Si supponga, ad esempio, che il file context.xml contenga l'elemento seguente:

<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$$"
/>

In questo caso, è possibile cambiarlo come illustrato nell'esempio seguente:

<Resource
    name="jdbc/dbconnection"
    type="javax.sql.DataSource"
    url="${postgresdb.connectionString}"
    driverClassName="org.postgresql.Driver"
    username="${postgresdb.username}"
    password="${postgresdb.password}"
/>

Per assicurarsi che la sostituzione dei parametri venga eseguita per qualsiasi file context.xml all'interno della cartella META-INF all'interno di un file con estensione war distribuito, assicurarsi di impostare la CATALINA_OPTS variabile di ambiente come illustrato nell'esempio seguente:

export CATALINA_OPTS="-Dorg.apache.tomcat.util.digester.PROPERTY_SOURCE=org.apache.tomcat.util.digester.EnvironmentPropertySource"

Effettuare il provisioning di un piano di servizio app

Dall'elenco dei piani di servizio disponibili nei prezzi del servizio app, selezionare il piano le cui specifiche soddisfano o superano quelle dell'hardware di produzione corrente.

Nota

Se si prevede di eseguire distribuzioni staging/canary o di usare gli slot di distribuzione, il piano di servizio app deve includere tale capacità aggiuntiva. È consigliabile usare piani Premium o superiori per le applicazioni Java. Per altre informazioni, vedere Configurare gli ambienti di gestione temporanea nel Servizio app di Azure.

Creare quindi il piano di servizio app. Per altre informazioni, vedere Gestire un piano di servizio app in Azure.

Creare e distribuire app Web

È necessario creare un'app Web nel piano di servizio app (scegliendo una versione di Tomcat come stack di runtime) per ogni file WAR distribuito nel server Tomcat.

Nota

Sebbene sia possibile distribuire più file WAR in un'unica app Web, questo approccio non è consigliabile. La distribuzione di più file WAR in un'unica app Web impedisce il ridimensionamento di ogni applicazione in base alle proprie esigenze di utilizzo, aumentando anche la complessità delle pipeline di distribuzione successive. Se più applicazioni devono essere disponibili in un singolo URL, provare a usare una soluzione di routing come il gateway applicazione di Azure.

Applicazioni Maven

Se l'applicazione viene compilata da un file POM Maven, usare il plug-in Webapp per Maven per creare l'app Web e distribuire l'applicazione.

Applicazioni non Maven

Se non è possibile usare il plug-in Maven, sarà necessario effettuare il provisioning dell'app Web tramite altri meccanismi, ad esempio:

Una volta creata l'app Web, usare uno dei meccanismi di distribuzione disponibili per distribuire l'applicazione.

Eseguire la migrazione delle opzioni di runtime JVM

Se l'applicazione richiede opzioni di runtime specifiche, usare il meccanismo più appropriato per specificarle.

Popolare i segreti

Usare le impostazioni dell'applicazione per archiviare i segreti specifici dell'applicazione. Se si intende usare gli stessi segreti tra più applicazioni o se sono necessari criteri di accesso e funzionalità di controllo con granularità fine, usare Azure Key Vault.

Configurare un dominio personalizzato e SSL

Se l'applicazione Web sarà visibile in un dominio personalizzato, sarà necessario eseguirne il mapping a tale dominio. Per altre informazioni, vedere Esercitazione: Eseguire il mapping di un nome DNS personalizzato esistente a app Azure Servizio.

Sarà quindi necessario associare il certificato SSL per tale dominio all'app Web del servizio app. Per altre informazioni, vedere Proteggere un nome DNS personalizzato con un binding SSL nel servizio app di Azure.

Importare certificati back-end

Tutti i certificati per la comunicazione con i sistemi back-end, ad esempio i database, devono essere resi disponibili al servizio app. Per altre informazioni, vedere Aggiungere un certificato SSL nel servizio app.

Eseguire la migrazione di origini dati, librerie e risorse JNDI

Per la procedura di configurazione dell'origine dati, vedere la sezione Origini dati dell'articolo Configurare un'app Java Linux per il servizio app Azure.

Per altre istruzioni sulle origini dati, vedere le sezioni seguenti sulle procedure sulle origini dati JNDI nella documentazione di Tomcat:

Eseguire la migrazione di eventuali altre dipendenze del classpath a livello di server, seguendo la stessa procedura indicata per i file JAR delle origini dati.

Eseguire la migrazione di eventuali altre risorse JDNI condivise a livello di server.

Nota

Se si sta usando l'architettura consigliata di un solo file WAR per ogni app Web, provare a eseguire la migrazione delle librerie di classpath a livello di server e delle risorse JNDI nell'applicazione. Questo approccio semplifica notevolmente la governance dei componenti e la gestione delle modifiche.

Eseguire la migrazione della configurazione rimanente

Al termine della sezione precedente, si avrà la configurazione del server personalizzabile in /home/tomcat/conf.

Completare la migrazione copiando eventuali altre configurazioni, ad esempio aree di autenticazione e JASPIC

Eseguire la migrazione dei processi pianificati

Per eseguire processi pianificati in Azure, è consigliabile usare un trigger Timer per Funzioni di Azure. Non è necessario eseguire la migrazione del codice del processo stesso in una funzione. La funzione può semplicemente richiamare un URL nell'applicazione per attivare il processo. Se le esecuzioni di processi devono essere richiamate dinamicamente e/o monitorate a livello centrale, provare a usare Spring Batch.

In alternativa, è possibile creare un'app per la logica con un trigger Ricorrenza per richiamare l'URL senza scrivere codice all'esterno dell'applicazione. Per altre informazioni, vedere Panoramica di App per la logica di Azure e Creare, pianificare ed eseguire attività e flussi di lavoro ricorrenti con il trigger Ricorrenza in App per la logica di Azure.

Nota

Per evitare un uso improprio, potrebbe essere necessario assicurarsi che l'endpoint di chiamata del processo richieda le credenziali. In questo caso, la funzione di trigger dovrà fornire le credenziali.

Riavvio e smoke test

Infine, sarà necessario riavviare l'app Web per applicare tutte le modifiche alla configurazione. Al termine del riavvio, verificare che l'applicazione venga eseguita correttamente.

Dopo la migrazione

Ora che è stata eseguita la migrazione dell'applicazione al servizio app di Azure, è necessario verificare che funzioni come previsto. Una volta completata questa operazione, sono disponibili alcune raccomandazioni per rendere l'applicazione maggiormente nativa del cloud.

Consigli