Questa pagina illustra le istruzioni per la migrazione dai runtime Python di prima generazione a quelli di seconda generazione. Per eseguire l'upgrade dell'app di seconda generazione in modo da utilizzare la versione di Python supportata più recente, consulta Eseguire l'upgrade di un'applicazione esistente.
Il 31 gennaio 2024 è terminato il supporto di Python 2.7. Le applicazioni Python 2.7 esistenti continueranno a essere eseguite e a ricevere traffico. Tuttavia, App Engine potrebbe bloccare il nuovo deployment delle applicazioni che utilizzano i runtime dopo la data di fine del supporto. Ti consigliamo di eseguire la migrazione alla versione più recente di Python supportata utilizzando le linee guida riportate in questa pagina.
La migrazione al runtime di Python 3 ti consente di utilizzare funzionalità del linguaggio aggiornate
e di creare app più portabili, con codice idiomatico. Il runtime di Python 3
utilizza la versione più recente dell'interprete Python open source fornito dalla
Python Software Foundation.
Le app integrate nel runtime di Python 3 possono utilizzare l'ampio ecosistema di pacchetti e framework di Python nella tua app, inclusi quelli che utilizzano codice C, dichiarando le dipendenze in un file requirements.txt
.
Panoramica del processo di migrazione del runtime
Ti consigliamo il seguente approccio incrementale alla migrazione del runtime, in cui mantieni un'applicazione funzionante e testabile durante tutto il processo:
Esegui l'upgrade dell'app per renderla compatibile con Python 3.
Sono disponibili diverse soluzioni per aiutarti con questo upgrade. Ad esempio, utilizza Six, Python-Future o Python-Modernize.
Per ulteriori informazioni su questo passaggio del processo di migrazione del runtime, consulta Porting Python 2 Code to Python 3 sul sito di documentazione della Python Software Foundation.
Scegli una di queste strategie di implementazione per qualsiasi servizio incluso in App Engine utilizzato dalla tua app:
Esegui la migrazione dei servizi integrati precedenti nella tua app Python 2 a servizi Google Cloud non integrati, servizi di terze parti o altre alternative consigliate.
Continua a utilizzare i servizi legacy raggruppati nelle tue app Python 3. Questo approccio ti offre la flessibilità di passare a servizi non raggruppati in un secondo momento nel ciclo di migrazione.
Assicurati di testare l'app dopo la migrazione di ogni servizio.
Prepara i file di configurazione di App Engine per il runtime Python 3. Diverse modifiche importanti influiscono sulle impostazioni di configurazione in
app.yaml
, tra cui, a titolo esemplificativo:- Ora si presume che le app siano a prova di thread. Se la tua applicazione non è sicura per i thread, devi impostare
max_concurrent_requests
inapp.yaml
su 1. Questa impostazione potrebbe comportare la creazione di più istanze di quanto necessario per un'app sicura per i thread e comportare costi non necessari. Il file
app.yaml
non inoltra più le richieste ai tuoi script. Devi invece utilizzare un framework web con routing in-app e aggiornare o rimuovere tutti gli handlerscript
inapp.yaml
. Per un esempio di come eseguire questa operazione con il framework Flask, consulta l'esempio di codice della guida alla migrazione di App Engine su GitHub.Per scoprire di più su come modificare questo e altri file di configurazione, consulta la sezione File di configurazione.
- Ora si presume che le app siano a prova di thread. Se la tua applicazione non è sicura per i thread, devi impostare
Nei runtime di seconda generazione, i log delle app non sono più nidificati nei log delle richieste. Per visualizzare la visualizzazione nidificata dei log delle richieste e delle app in Esplora log sono necessari passaggi aggiuntivi. Per ulteriori informazioni, consulta Eseguire la migrazione a Cloud Logging.
Esegui test e deployment dell'app di cui è stato eseguito l'upgrade in un ambiente Python 3.
Dopo che tutti i test sono stati superati, esegui il deployment dell'app di cui è stato eseguito l'upgrade su App Engine, ma impedisci che il traffico venga instradato automaticamente alla nuova versione. Utilizza la suddivisione del traffico per eseguire lentamente la migrazione del traffico dall'app nel runtime Python 2 all'app nel runtime Python 3. Se riscontri problemi, puoi instradare tutto il traffico a una versione stabile finché il problema non viene risolto.
Per esempi su come convertire le app Python 2 in Python 3, puoi fare riferimento a queste risorse aggiuntive.
Differenze principali tra i runtime Python 2 e Python 3
La maggior parte delle modifiche da apportare durante la migrazione del runtime è dovuta alle seguenti differenze tra i runtime Python 2 e Python 3:
- Differenze nell'utilizzo della memoria
- Differenze di utilizzo della CPU
- Differenze nelle intestazioni delle richieste
- Differenze tra i worker Gunicorn
- Problemi di compatibilità tra Python 2 e Python 3
- Servizi integrati di App Engine nel runtime di Python 3
- Differenze tra i file di configurazione
- È necessario un framework web per instradare le richieste di contenuti dinamici
- App con solo contenuti statici
- Differenze nei test
- Differenze di deployment
Differenze nell'utilizzo della memoria
I runtime di seconda generazione hanno una base di riferimento dell'utilizzo della memoria più elevata rispetto ai runtime di prima generazione. Ciò è dovuto a diversi fattori, come versioni diverse delle immagini di base e differenze nel modo in cui le due generazioni calcolano l'utilizzo della memoria.
I runtime di seconda generazione calcolano l'utilizzo della memoria dell'istanza come la somma di ciò che viene utilizzato da un processo dell'applicazione e del numero di file dell'applicazione memorizzati nella cache dinamicamente in memoria. Per evitare che le applicazioni che utilizzano molta memoria vengano chiuse a causa del superamento dei limiti di memoria, esegui l'upgrade a una classe di istanze più grande con più memoria.
Differenze nell'utilizzo della CPU
I runtime di seconda generazione possono mostrare una linea di base più elevata dell'utilizzo della CPU al primo avvio dell'istanza. A seconda della configurazione della scalabilità di un'applicazione, questo potrebbe avere effetti collaterali indesiderati, ad esempio un numero di istanze superiore a quello previsto se un'applicazione è configurata per la scalabilità in base all'utilizzo della CPU. Per evitare questo problema, esamina e testa le configurazioni di scalabilità dell'applicazione per assicurarti che il numero di istanze sia accettabile.
Differenze nelle intestazioni delle richieste
I runtime di prima generazione consentono di inoltrare all'applicazione le intestazioni di richiesta con trattini bassi
(ad es. X-Test-Foo_bar
). I runtime di seconda generazione introducono Nginx nell'architettura host. A seguito di questa
variazione, i runtime di seconda generazione sono configurati per rimuovere automaticamente
le intestazioni con trattini bassi (_
). Per evitare problemi con le applicazioni, evita di utilizzare
tracci bassi nelle intestazioni delle richieste delle applicazioni.
Differenze tra i worker Gunicorn
Per gli ambienti di runtime Python 3 e versioni successive, il numero di worker Gunicorn ha un impatto diretto sull'utilizzo della memoria. L'aumento dell'utilizzo della memoria è direttamente proporzionale all'aumento del numero di worker. Per ridurre il consumo di memoria, valuta la possibilità di ridurre il numero di worker Gunicorn. Consulta le best practice per i punti di contatto per istruzioni su come configurare il numero di worker Gunicorn
Problemi di compatibilità tra Python 2 e Python 3
Quando Python 3 è stato rilasciato per la prima volta nel 2008,
nel linguaggio sono state introdotte diverse modifiche non compatibili con le versioni precedenti. Alcune di queste modifiche richiedono solo aggiornamenti minori al codice, ad esempio la modifica dell'istruzione print
in una funzione print()
.
Altre modifiche potrebbero richiedere aggiornamenti significativi al codice, ad esempio l'aggiornamento della modalità di gestione di dati binari, testo e stringhe.
Molte librerie open source di uso comune, tra cui le librerie standard di Python, sono cambiate anche quando sono passate da Python 2 a Python 3.
Servizi integrati di App Engine nel runtime Python 3
Per ridurre lo sforzo e la complessità della migrazione, l'ambiente standard di App Engine ti consente di accedere a molti servizi e API legacy raggruppati nel runtime di Python 3, come Memcache. L'app Python 3 può chiamare le API dei servizi in bundle tramite le librerie idiomatiche del linguaggio e accedere alle stesse funzionalità del runtime Python 2.
Hai anche la possibilità di utilizzare i prodotti Google Cloud che offrono funzionalità simili a quelle dei servizi in bundle precedenti. Ti consigliamo di considerare la migrazione ai prodotti Google Cloud non integrati, in quanto ti consente di usufruire dei miglioramenti continui e delle nuove funzionalità.
Per i servizi in bundle che non sono disponibili come prodotti separati in Google Cloud, come l'elaborazione di immagini, la ricerca e la messaggistica, puoi utilizzare i nostri fornitori di terze parti suggeriti o altre soluzioni alternative.
File di configurazione
Prima di poter eseguire l'app nel runtime Python 3 dell'ambiente standard di App Engine, potresti dover modificare alcuni dei file di configurazione utilizzati da App Engine:
app.yaml
. Il comportamento di alcuni campi nel file di configurazioneapp.yaml
è stato modificato. Rimuovi i campi deprecati e aggiorna gli altri campi come descritto nella guida alla migrazione.requirements.txt
. Crea questo file per installare dipendenze di terze parti, inclusi i pacchetti Python che richiedono estensioni C native. App Engine installa automaticamente queste dipendenze durante il deployment dell'app nel runtime Python 3. In precedenza, per installare le dipendenze nel runtime Python 2, dovevano essere elencate le librerie copiate o auto-aggregate in questo file, quindi doveva essere eseguito un comandopip install -t lib -r requirements.txt
o elencate le librerie di terze parti "incorporate" richieste dall'app nel file app.yaml.appengine_config.py
. Questo file non viene utilizzato nel runtime di Python 3 e viene ignorato se viene eseguito il deployment. In precedenza, nel runtime di Python 2, questo file veniva utilizzato per configurare i moduli Python e indirizzare l'app a librerie di terze parti copiate o auto-raggruppate.
Framework web necessario per instradare le richieste di contenuti dinamici
Nel runtime di Python 2, puoi creare gestori di URL nel file app.yaml
per specificare l'app da eseguire quando viene richiesto un URL o un pattern URL specifico.
In Python 3, l'app deve utilizzare un framework web come Flask o Django per inoltrare le richieste di contenuti dinamici anziché utilizzare i gestori URL in app.yaml
. Per i contenuti statici, puoi continuare a creare gestori di URL nel file app.yaml
della tua app.
App con solo contenuti statici
Quando ospiti una web app statica su App Engine,
devi specificare gli handler nel file app.yaml
per mappare gli URL ai file statici.
In Python 2, se una richiesta non corrisponde a nessuno degli handler specificati nel
app.yaml
file, App Engine restituisce un codice di errore 404
.
In Python 3, se una richiesta non corrisponde a nessuno degli elaboratori, App Engine cerca un file main.py
e restituisce un errore 5xx
se non viene trovato un file main.py
. Poiché le app App Engine con solo contenuti statici non richiedono un filemain.py
, la maggior parte degli utenti visualizza questo errore, oltre agli errori di avvio dell'istanza nei log dell'app.
Per mantenere lo stesso comportamento di restituzione di un errore 404
quando nessuno degli elaboratori statici corrisponde ed evitare errori nei log, puoi:
- Aggiungi un gestore statico catch-all che rimandi a una directory vuota nel file
app.yaml
- Aggiungi una semplice app dinamica nel file
main.py
per restituire un errore404
Esempi di utilizzo di entrambe le opzioni:
app.yaml
Crea una directory vuota nella directory principale dell'app, ad esempio empty/
.
Nella sezione del gestore del file app.yaml
, crea un nuovo gestore alla fine per rilevare tutti gli altri pattern URL e specifica la directory empty
negli elementi static_files
e upload
:
handlers:
- url:
.
.
.
- url: /(.*)$
static_files: empty/\1
upload: empty/.*$
main.py
Crea un file main.py
e aggiungi il codice seguente per restituire un errore 404
:
def app(env, start_response):
start_response('404 Not Found', [('Content-Type','text/html')])
return [b"Not Found"]
Test
Ti consigliamo di utilizzare un approccio di test idiomatico per Python anziché dipendere da dev_appserver
. Ad esempio, puoi utilizzare venv
per creare un ambiente Python 3 locale isolato. Qualsiasi framework di test Python standard può essere utilizzato per scrivere test di unità, integrazione e di sistema. Puoi anche valutare la possibilità di configurare le versioni di sviluppo dei tuoi servizi o utilizzare gli emulatori locali disponibili per molti prodotti Google Cloud.
Se vuoi, puoi utilizzare la versione di anteprima di dev_appserver
che supporta Python 3. Per scoprire di più su questa funzionalità di test, consulta
Utilizzo del server di sviluppo locale.
Deployment in corso…
I deployment tramite appcfg.py
non sono
supportati per Python 3.
Utilizza invece lo strumento a riga di comando gcloud
per eseguire il deployment dell'app.
Logging
Il logging nel runtime di Python 3 segue lo standard di logging in Cloud Logging. Nel runtime di Python 3, i log delle app non sono più raggruppati con i log delle richieste, ma sono separati in record diversi. Per scoprire di più sulla lettura e sulla scrittura dei log nel runtime di Python 3, consulta la guida alla registrazione.
Risorse aggiuntive per la migrazione
Per ulteriori informazioni su come eseguire la migrazione delle app App Engine ai servizi Cloud autonomi o al runtime Python 3, puoi consultare queste risorse di App Engine:
- Codelab e video sulla migrazione delle app serverless
- Esempi di migrazione di app da Python 2 a Python 3 donati dalla community