Migrazione da Python 2.7 al runtime Python 3 più recente

Questa pagina contiene le istruzioni per eseguire la migrazione dal da prima a seconda generazione i runtime Python. 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.

Python 2.7 ha raggiunto la fine del supporto il 31 gennaio 2024. Le applicazioni Python 2.7 esistenti continueranno a esistere per eseguire e 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 Python 3 possono utilizzare il ricco ecosistema di pacchetti di Python e i framework nella tua app, inclusi quelli che utilizzano il codice C, dichiarando di 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:

  1. Esegui l'upgrade dell'app in modo che sia 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 Trasferimento del codice Python 2 a Python 3 sulla Python Software Foundation sito di documentazione.

  2. Scegli una di queste strategie di implementazione per qualsiasi App Engine servizio in bundle utilizzato dalla tua app:

    1. Esegui la migrazione dei servizi integrati legacy nella tua app Python 2 a servizi Google Cloud non integrati, servizi di terze parti o altre alternative consigliate.

    2. Continua a utilizzare i servizi legacy raggruppati nelle tue app Python 3. Questo offre la flessibilità di passare ai servizi non in bundle più avanti nel di migrazione.

    Assicurati di testare l'app dopo la migrazione di ciascun servizio.

  3. Prepara la configurazione di App Engine per il runtime Python 3. Alcune importanti modifiche interessano impostazioni di configurazione in app.yaml, incluse, a titolo esemplificativo:

    • Ora si presume che le app siano sicure per i thread. Se la tua applicazione non è sicura per i thread, devi impostare max_concurrent_requests in app.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. Invece, Devi usare un framework web con routing in-app e aggiornare oppure rimuovi tutti i gestori script in app.yaml. Per un esempio di come fare con il framework Flask, controlla Esempio di codice della guida alla migrazione di App Engine in GitHub.

      Per saperne di più sulla modifica di questo e di altri file di configurazione, consulta File di configurazione.

  4. 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.

  5. 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

I runtime di seconda generazione registrano una base di 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 usano molta memoria utilizzino l'istanza arresti anomali dovuti al superamento dei limiti di memoria, esegui l'upgrade a una versione classe dell'istanza con più memoria.

Differenze di 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 di scalabilità di un'applicazione, effetti collaterali imprevisti, come un conteggio delle istanze più elevato del previsto è 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 nell'intestazione della richiesta

I runtime di prima generazione consentono di inoltrare all'applicazione le intestazioni di richiesta con trattini bassi (ad es. X-Test-Foo_bar). Di seconda generazione introduce 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 i trattini bassi nelle intestazioni delle richieste delle applicazioni.

Differenze tra i worker Gunicorn

Per i runtime Python 3 e versioni successive, il numero di worker Gunicorn ha un impatto diretto su memoria utilizzata. L'aumento dell'utilizzo della memoria è direttamente proporzionale al di 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 di minore entità al codice, ad esempio modificando l'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.

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 le attività di migrazione e la complessità, l'ambiente standard di App Engine consente per accedere a molti dei servizi in bundle legacy e di API nel file Python 3 runtime, ad esempio 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 con funzionalità simili a quelle dei precedenti servizi in bundle. Ti consigliamo di considerare la migrazione ai prodotti Google Cloud non integrati, poiché in questo modo potrai 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 dello standard App Engine potrebbe essere necessario modificare alcuni file di configurazione App Engine utilizza:

Framework web necessario per indirizzare le richieste di contenuti dinamici

Nel runtime di Python 2, puoi creare gestori di URL nel file app.yaml per specificare quale app eseguire quando viene richiesto un URL o un pattern URL specifico.

Nel runtime di Python 3, la tua app deve utilizzare un framework web come Flask o Django per indirizzare le richieste per i contenuti dinamici anziché utilizzare Gestori di 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 ad alcun gestore, App Engine cerca un file main.py e restituisce un errore 5xx se un file main.py non è trovato. Poiché le app App Engine con solo contenuti statici non richiedono un main.py file, la maggior parte degli utenti vede questo errore, oltre a vedere l'istanza errori di avvio 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 un'app dinamica semplice nel file main.py per restituire un errore 404

Esempi di utilizzo di una delle due opzioni:

app.yaml

Crea una directory vuota nella directory dell'app principale, ad esempio empty/. Nella sezione relativa al gestore del file app.yaml, crea un nuovo gestore alla fine per individuare tutti gli altri pattern URL e specifica la directory empty nel 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 a Python, anziché rispetto alla dipendenza 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.

Facoltativamente, 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 non supportato per Python 3. Utilizza invece la gcloud strumento a riga di comando per eseguire il deployment della tua app.

Logging

Il logging nel runtime Python 3 segue lo standard di logging 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 apprendere sulla lettura e sulla scrittura dei log nel runtime Python 3, consulta guida al logging.

Risorse aggiuntive per la migrazione

Per ulteriori informazioni su come eseguire la migrazione delle app di App Engine a dai servizi Cloud autonomi o dal runtime Python 3, puoi fare riferimento a questi Risorse di App Engine: