Questa pagina contiene 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 che utilizzi l'ultima versione supportata di Python, consulta Eseguire l'upgrade di un'applicazione esistente.
Python 2.7 è deprecato. Non potrai eseguire il deployment delle applicazioni Python 2.7, anche se la tua organizzazione in precedenza utilizzava un criterio dell'organizzazione per riattivare i deployment dei runtime legacy. Le applicazioni Python 2.7 esistenti continueranno a essere eseguite e a ricevere traffico. Ti consigliamo di eseguire la migrazione all'ultima versione supportata di Python.
La migrazione al runtime Python 3 ti consente di utilizzare funzionalità del linguaggio aggiornate e di creare app più portatili, con codice idiomatico. Il runtime Python 3
utilizza l'ultima versione dell'interprete Python open source fornito dalla
Python Software Foundation.
Le app create nel runtime Python 3 possono utilizzare il ricco ecosistema di pacchetti e framework di Python nella tua app, inclusi quelli che utilizzano il codice C, dichiarando le dipendenze in un file requirements.txt.
Panoramica del processo di migrazione del runtime
Ti consigliamo di adottare il seguente approccio incrementale alla migrazione del runtime, in cui mantieni un'applicazione funzionante e testabile durante l'intero processo:
Esegui l'upgrade dell'app in modo che sia compatibile con Python 3.
Sono disponibili diverse soluzioni per facilitare questo upgrade. Ad esempio, utilizza Six, Python-Future o Python-Modernize.
Per ulteriori informazioni su questo passaggio del processo di migrazione del runtime, consulta Trasferimento del codice Python 2 a Python 3 sul sito di documentazione della Python Software Foundation.
Scegli una di queste strategie di implementazione per qualsiasi servizio in bundle di App Engine utilizzato dalla tua app:
Esegui la migrazione dei servizi in bundle legacy nella tua app Python 2 a servizi non in bundle Google Cloud servizi, di terze parti servizi, o altre alternative consigliate.
Continua a utilizzare i servizi in bundle legacy nelle tue app Python 3. Questo approccio ti offre la flessibilità di passare ai servizi non in bundle in un secondo momento nel ciclo di migrazione.
Google Cloud
Assicurati di testare l'app dopo aver eseguito 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 nel file
app.yaml, tra cui, a titolo esemplificativo:- Se utilizzi i servizi in bundle legacy nelle tue app Python 3, aggiungi l'impostazione
app_engine_bundled_servicesnel fileapp.yamlper abilitare l'accesso a servizi in bundle specifici. - Ora si presuppone che le app siano thread-safe. Se la tua applicazione non è
thread-safe, devi impostare
max_concurrent_requestsinapp.yamlsu 1. Questa impostazione potrebbe comportare la creazione di più istanze di quelle necessarie per un'app thread-safe e comportare costi non necessari. Il file
app.yamlnon instrada più le richieste agli script. Devi invece utilizzare un framework web con routing in-app e aggiornare o rimuovere tutti i gestoriscriptinapp.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ù sulla modifica di questo e di altri file di configurazione, consulta la sezione File di configurazione.
- Se utilizzi i servizi in bundle legacy nelle tue app Python 3, aggiungi l'impostazione
Nei runtime di seconda generazione, i log delle app non sono più nidificati all'interno dei log delle richieste. Sono necessari passaggi aggiuntivi per visualizzare la visualizzazione nidificata dei log delle richieste e delle app in Esplora log. Per ulteriori informazioni, consulta Eseguire la migrazione a Cloud Logging.
Testa ed esegui il deployment dell'app di cui hai eseguito l'upgrade in un ambiente Python 3.
Dopo che tutti i test sono stati superati, esegui il deployment dell'app di cui hai eseguito l'upgrade in App Engine, ma impedisci il routing automatico del traffico 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 di come convertire le app Python 2 in Python 3, puoi consultare queste risorse aggiuntive.
Differenze principali tra i runtime Python 2 e Python 3
La maggior parte delle modifiche che devi apportare durante la migrazione del runtime deriva dalle seguenti differenze tra i runtime Python 2 e Python 3:
- Differenze nella memoria utilizzata
- Differenze nell'utilizzo della CPU
- Differenze nelle intestazioni delle richieste
- Differenze tra i worker Gunicorn
- Problemi di compatibilità tra Python 2 e Python 3
- Servizi in bundle di App Engine nel runtime Python 3
- Differenze nei file di configurazione
- È necessario un framework web per instradare le richieste di contenuti dinamici
- App con solo contenuti statici
- Differenze nei test
- Differenze nel deployment
Differenze nella memoria utilizzata
I runtime di seconda generazione registrano una baseline di memoria utilizzata più elevata rispetto ai runtime di prima generazione. Ciò è dovuto a diversi fattori, come le diverse versioni dell'immagine di base e le differenze nel modo in cui le due generazioni calcolano l'utilizzo della memoria.
I runtime di seconda generazione calcolano la memoria utilizzata dall'istanza come la somma di ciò che utilizza un processo dell'applicazione e del numero di file dell'applicazione memorizzati nella cache in modo dinamico in memoria. Per evitare che le applicazioni che richiedono molta memoria subiscano arresti anomali dell'istanza a causa del superamento dei limiti di memoria, esegui l'upgrade a una classe di istanza più grande con più memoria.
Differenze nell'utilizzo della CPU
I runtime di seconda generazione possono registrare una baseline di utilizzo della CPU più elevata all'avvio a freddo dell'istanza. A seconda della configurazione di scalabilità di un'applicazione, questa operazione potrebbe avere effetti collaterali indesiderati, ad esempio un numero di istanze superiore a quello previsto se un'applicazione è configurata per scalare 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 l'inoltro delle intestazioni delle richieste con trattini bassi (ad es. X-Test-Foo_bar) all'applicazione. I runtime di seconda generazione introducono Nginx nell'architettura host. Di conseguenza, i runtime di seconda generazione sono configurati per rimuovere automaticamente le intestazioni con trattini bassi (_). Per evitare problemi con l'applicazione, evita di utilizzare i trattini bassi nelle intestazioni delle richieste dell'applicazione.
Differenze tra i worker Gunicorn
Per i runtime Python 3+, il numero di worker Gunicorn ha un impatto diretto sulla memoria utilizzata. L'aumento della memoria utilizzata è direttamente proporzionale all'aumento del numero di worker. Per ridurre il consumo di memoria, valuta la possibilità di ridurre il numero di worker Gunicorn. Per istruzioni sulla configurazione del numero di worker Gunicorn, consulta le best practice per il punto di ingresso .
Problemi di compatibilità tra Python 2 e Python 3
Quando Python 3 è stato rilasciato per la prima volta nel 2008,
sono state introdotte diverse modifiche incompatibili con le versioni precedenti
del linguaggio. 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 del modo in cui gestisci dati binari, testo e stringhe.
Anche molte librerie open source, incluse le librerie standard di Python, sono state modificate quando sono passate da Python 2 a Python 3.
Servizi in bundle di App Engine nel runtime Python 3
Per ridurre l'impegno e la complessità della migrazione, l'ambiente standard di App Engine ti consente di accedere a molti servizi e API in bundle legacy nel runtime Python 3, ad esempio Memcache. La tua app Python 3 può chiamare le API dei servizi in bundle tramite librerie idiomatiche del linguaggio e accedere alle stesse funzionalità del runtime Python 2.
Puoi anche utilizzare Google Cloud prodotti che offrono funzionalità simili a quelle dei servizi in bundle legacy. Ti consigliamo di valutare la migrazione ai prodotti non in bundle Google Cloud , in quanto ti consentono di sfruttare i miglioramenti continui e le nuove funzionalità.
Per i servizi in bundle non disponibili come prodotti separati in Google Cloud, come l'elaborazione delle immagini, la ricerca e la messaggistica, puoi utilizzare i provider 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 tutti i campi ritirati e aggiorna gli altri campi come descritto in the guida alla migrazione.requirements.txt. Crea questo file per installare le 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, dovevi elencare le librerie copiate o in bundle automatico in questo file, quindi eseguire un comandopip install -t lib -r requirements.txt.appengine_config.py. Questo file non viene utilizzato nel runtime Python 3 e viene ignorato se viene eseguito il deployment. In precedenza, nel runtime Python 2, questo file veniva utilizzato per configurare i moduli Python e indirizzare l'app alle librerie di terze parti copiate o in bundle automatico.
È necessario un framework web per instradare le richieste di contenuti dinamici
Nel runtime 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.
Nel runtime Python 3, l'app deve utilizzare un framework web come Flask o Django per instradare le richieste di contenuti dinamici anziché utilizzare i gestori di URL in app.yaml. Per i contenuti statici, puoi continuare a creare gestori di URL
nel file app.yaml dell'app.
App con solo contenuti statici
Quando ospiti un'app web statica su App Engine, devi specificare i gestori nel file app.yaml per mappare gli URL ai file statici.
In Python 2, se una richiesta non corrisponde a nessuno dei gestori specificati nel
app.yaml file, App Engine restituisce un codice di errore 404.
In Python 3, se una richiesta non corrisponde a nessuno dei gestori, 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 file main.py, la maggior parte degli utenti visualizza questo errore, oltre agli errori di avvio dell'istanza nei log delle app.
Per mantenere lo stesso comportamento di restituzione di un errore 404 quando nessuno dei gestori statici corrisponde e per evitare errori nei log, puoi:
- Aggiungere un gestore statico catch-all che rimanda a una directory vuota nel file
app.yaml - Aggiungere una semplice app dinamica nel file
main.pyper restituire un errore404
Esempi di utilizzo di una delle due opzioni:
app.yaml
Crea una directory vuota nella directory principale dell'app, ad esempio empty/.
Nella sezione dei gestori del file app.yaml, crea un nuovo gestore alla fine per intercettare
tutti gli altri pattern di 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 seguente codice 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. Puoi utilizzare qualsiasi framework di test Python standard per scrivere i test unitari, di integrazione e di sistema. Potresti anche prendere in considerazione la configurazione di versioni di sviluppo dei tuoi servizi o l'utilizzo degli emulatori locali disponibili per molti prodotti Google Cloud.
Facoltativamente, puoi utilizzare la versione di anteprima di dev_appserver che supporta Python 3. Per scoprire di più su questa funzionalità di test, consulta
Utilizzare il server di sviluppo locale.
Deployment
I deployment tramite appcfg.py non sono supportati per Python 3.
Utilizza invece la gcloud riga di comando
per eseguire il deployment dell'app.
Logging
Il logging nel runtime Python 3 segue lo standard di logging in Cloud Logging. Nel runtime Python 3, i log delle app non sono più in bundle con i log delle richieste, ma sono separati in record diversi. Per scoprire di più sulla lettura e la scrittura dei log nel runtime Python 3, consulta la guida al logging.
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 forniti dalla community