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:
- Eseguire la migrazione di applicazioni Tomcat ai contenitori nel servizio Azure Kubernetes
- Eseguire la migrazione di applicazioni Tomcat alle macchine virtuali di Azure (indicazioni in pianificazione)
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.
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.
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 Montare Archiviazione di Azure come condivisione locale in servizio app.
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, è necessario effettuare il refactoring per rimuovere tali dipendenze. Ad esempio, potrebbe essere necessario sostituire qualsiasi uso di o \
nei percorsi del /
file system con File.Separator
o Paths.get
se l'applicazione è in esecuzione in Windows.
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.
Post-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
Se si è scelto di usare la directory /home per l'archiviazione dei file, provare a sostituirla con Archiviazione di Azure.
Se nella directory /home è presente una configurazione contenente stringhe di connessione, chiavi SSL e altre informazioni segrete, provare a usare una combinazione di Azure Key Vault e/o inserimento di parametri con le impostazioni dell'applicazione laddove possibile.
Provare a usare gli slot di distribuzione per distribuzioni affidabili senza tempi di inattività.
Progettare e implementare una strategia DevOps. Per mantenere l'affidabilità aumentando al tempo stesso la velocità di sviluppo, è consigliabile automatizzare le distribuzioni e i test con Azure Pipelines. Se si usano gli slot di distribuzione, è possibile automatizzare la distribuzione in uno slot, seguita dallo scambio di slot.
Progettare e implementare una strategia di continuità aziendale e ripristino di emergenza. Per le applicazioni cruciali, considerare un'architettura di distribuzione in più aree.