1. Panoramica
La serie di codelab Serverless Migration Station (esercitazioni pratiche e autonome) e i video correlati hanno lo scopo di aiutare gli sviluppatori serverless di Google Cloud a modernizzare le loro applicazioni guidandoli attraverso una o più migrazioni, principalmente abbandonando i servizi legacy. In questo modo, le tue app sono più portatili e hai più opzioni e flessibilità, il che ti consente di integrarti e accedere a una gamma più ampia di prodotti cloud e di eseguire più facilmente l'upgrade alle versioni più recenti del linguaggio. Sebbene inizialmente si concentri sui primi utenti di Cloud, principalmente gli sviluppatori di App Engine (ambiente standard), questa serie è abbastanza ampia da includere altre piattaforme serverless come Cloud Functions e Cloud Run o altrove, se applicabile.
Lo scopo di questo codelab è mostrare agli sviluppatori di App Engine Python 2 come eseguire la migrazione da App Engine Memcache a Cloud Memorystore (per Redis). Esiste anche una migrazione implicita da App Engine ndb a Cloud NDB, ma questa è trattata principalmente nel codelab del modulo 2. Consulta questa risorsa per informazioni più dettagliate.
Imparerai a utilizzare
- Configura un'istanza Cloud Memorystore (dalla console Cloud o dallo strumento
gcloud) - Configura un connettore di accesso VPC serverless (da Cloud Console o dallo strumento
gcloud) - Esegui la migrazione da App Engine Memcache a Cloud Memorystore
- Implementa la memorizzazione nella cache con Cloud Memorystore in un'app di esempio
- Migrazione da App Engine
ndba Cloud NDB
Che cosa ti serve
- Un progetto Google Cloud con un account di fatturazione attivo (questo non è un codelab senza costi)
- Competenze di base di Python
- Conoscenza pratica dei comandi Linux più comuni
- Conoscenza di base dello sviluppo e del deployment di app App Engine
- Un'app App Engine del modulo 12 funzionante (completa il codelab del modulo 12 [consigliato] o copia l'app del modulo 12 dal repository)
Sondaggio
Come utilizzerai questo tutorial?
Come valuteresti la tua esperienza con Python?
Come valuti la tua esperienza di utilizzo dei servizi Google Cloud?
2. Sfondo
Questo codelab mostra come eseguire la migrazione di un'app di esempio da App Engine Memcache (e NDB) a Cloud Memorystore (e Cloud NDB). Questa procedura prevede la sostituzione delle dipendenze dai servizi integrati di App Engine, rendendo le tue app più portatili. Puoi scegliere di rimanere su App Engine o prendere in considerazione il passaggio a una delle alternative descritte in precedenza.
Questa migrazione richiede più impegno rispetto alle altre di questa serie. La sostituzione consigliata per App Engine Memcache è Cloud Memorystore, un servizio di memorizzazione nella cache basato sul cloud completamente gestito. Memorystore supporta una coppia di motori di memorizzazione nella cache open source popolari, Redis e Memcached. Questo modulo di migrazione utilizza Cloud Memorystore for Redis. Per saperne di più, consulta la panoramica di Memorystore e Redis.
Poiché Memorystore richiede un server in esecuzione, è necessario anche Cloud VPC. In particolare, deve essere creato un connettore di accesso VPC serverless in modo che l'app App Engine possa connettersi all'istanza Memorystore tramite il relativo indirizzo IP privato. Al termine di questo esercizio, avrai aggiornato l'app in modo che, pur comportandosi come prima, Cloud Memorystore sia il servizio di memorizzazione nella cache, sostituendo il servizio Memcache di App Engine.
Questo tutorial inizia con l'app di esempio del modulo 12 in Python 2, seguito da un upgrade secondario facoltativo a Python 3. Se hai già familiarità con l'accesso ai servizi in bundle di App Engine da Python 3 tramite l'SDK App Engine per Python 3, puoi iniziare con la versione Python 3 dell'app di esempio del modulo 12. In questo modo, l'utilizzo dell'SDK verrà rimosso, poiché Memorystore non è un servizio in bundle di App Engine. L'apprendimento dell'utilizzo dell'SDK App Engine Python 3 non rientra nell'ambito di questo tutorial.
Questo tutorial prevede i seguenti passaggi chiave:
- Configurazione/preparazione
- Configura i servizi di memorizzazione nella cache
- Aggiorna i file di configurazione
- Aggiorna l'applicazione principale
3. Configurazione/preparazione
Prepara il progetto cloud
Ti consigliamo di riutilizzare lo stesso progetto che hai utilizzato per completare il codelab del modulo 12. In alternativa, puoi creare un nuovo progetto o riutilizzarne uno esistente. Ogni codelab di questa serie ha un "INIZIO" (il codice di base da cui partire) e una "FINE" (l'app di cui è stata eseguita la migrazione). Il codice FINISH viene fornito per consentirti di confrontare le tue soluzioni con le nostre in caso di problemi. Se qualcosa va storto, puoi sempre ripristinare lo stato iniziale. Questi punti di controllo sono progettati per assicurarti di imparare a eseguire le migrazioni.
Qualunque sia il progetto Cloud che utilizzi, assicurati che abbia un account di fatturazione attivo. Assicurati inoltre che App Engine sia abilitato. Esamina e assicurati di comprendere le implicazioni generali dei costi derivanti da questi tutorial. A differenza di altri codelab di questa serie, questo utilizza risorse cloud che non hanno un livello senza costi, pertanto per completare l'esercizio verranno sostenuti alcuni costi. Verranno fornite informazioni più specifiche sui costi, insieme a consigli per ridurre l'utilizzo, incluse istruzioni alla fine su come rilasciare le risorse per ridurre al minimo gli addebiti di fatturazione.
Ottieni l'app di esempio di base
A partire dal codice di base del modulo 12, questo codelab ti guida passo passo nella migrazione. Al termine, otterrai un'app del modulo 13 funzionante che assomiglia molto al codice in una delle cartelle FINISH. Ecco le risorse:
- INIZIO: Modulo 12 Python 2 (
mod12) o Python 3 (mod12b) - FINE: Modulo 13 Python 2 (
mod13a) o Python 3 (mod13b) - Intero repository di migrazione (clona o scarica ZIP)
La cartella START deve contenere i seguenti file:
$ ls README.md app.yaml main.py requirements.txt templates
Se inizi dalla versione Python 2, ci sarà anche un file appengine_config.py ed eventualmente una cartella lib se hai completato il codelab del modulo 12.
(Esegui di nuovo il deployment dell'app del modulo 12
I passaggi preparatori rimanenti:
- Riacquisisci familiarità con lo strumento a riga di comando
gcloud(se necessario) - (Esegui di nuovo il) deployment del codice del Modulo 12 in App Engine (se necessario)
Gli utenti di Python 2 devono eliminare e reinstallare la cartella lib con questi comandi:
rm -rf ./lib; pip install -t lib -r requirements.txt
Ora tutti (utenti di Python 2 e 3) devono caricare il codice su App Engine con questo comando:
gcloud app deploy
Una volta eseguito il deployment, verifica che l'app abbia lo stesso aspetto e funzioni come l'app del modulo 12, un'app web che monitora le visite e le memorizza nella cache per lo stesso utente per un'ora:

Poiché le visite più recenti vengono memorizzate nella cache, gli aggiornamenti della pagina dovrebbero caricarsi abbastanza rapidamente.
4. Configura i servizi di memorizzazione nella cache
Cloud Memorystore non è serverless. È necessaria un'istanza, in questo caso una che esegue Redis. A differenza di Memcache, Memorystore è un prodotto Cloud autonomo e non dispone di un livello senza costi, quindi assicurati di controllare le informazioni sui prezzi di Memorystore for Redis prima di procedere. Per ridurre al minimo i costi di questo esercizio, ti consigliamo la quantità minima di risorse per operare: un livello di servizio Basic e una capacità di 1 GB.
L'istanza Memorystore si trova su una rete diversa rispetto alla tua app App Engine (istanze), motivo per cui è necessario creare un connettore di accesso VPC serverless in modo che App Engine possa accedere alle tue risorse Memorystore. Per ridurre al minimo i costi VPC, scegli il tipo di istanza (f1-micro) e il numero minimo di istanze da richiedere (suggeriamo un minimo di 2 e un massimo di 3). Consulta anche la pagina con le informazioni sui prezzi di VPC.
Ripetiamo questi consigli per ridurre i costi mentre ti guidiamo nella creazione di ogni risorsa richiesta. Inoltre, quando crei risorse Memorystore e VPC in Cloud Console, nell'angolo in alto a destra viene visualizzato il calcolatore dei prezzi per ogni prodotto, che ti fornisce una stima dei costi mensili (vedi l'illustrazione di seguito). Questi valori vengono modificati automaticamente se cambi le opzioni. Ecco cosa dovresti vedere:

Entrambe le risorse sono obbligatorie e non importa quale crei per prima. Se crei prima l'istanza Memorystore, la tua app App Engine non può raggiungerla senza il connettore VPC. Allo stesso modo, se crei prima il connettore VPC, non c'è nulla su quella rete VPC con cui la tua app App Engine possa comunicare. In questo tutorial viene creata prima l'istanza Memorystore e poi il connettore VPC.
Una volta che entrambe le risorse sono online, aggiungi le informazioni pertinenti a app.yaml in modo che la tua app possa accedere alla cache. Puoi anche consultare le guide di Python 2 o Python 3 nella documentazione ufficiale. Ti consigliamo di consultare anche la guida alla memorizzazione nella cache dei dati nella pagina di migrazione di Cloud NDB ( Python 2 o Python 3).
Crea un'istanza di Cloud Memorystore
Poiché Cloud Memorystore non ha un livello senza costi, ti consigliamo di allocare la quantità minima di risorse per completare il codelab. Puoi ridurre al minimo i costi utilizzando queste impostazioni:
- Seleziona il livello di servizio più basso: Basic (impostazione predefinita della console: "Standard", impostazione predefinita di
gcloud: "Basic"). - Scegli la quantità minima di spazio di archiviazione: 1 GB (valore predefinito della console: 16 GB, valore predefinito di
gcloud: 1 GB). - In genere, le versioni più recenti di qualsiasi software richiedono la quantità maggiore di risorse, ma anche la selezione della versione più vecchia non è consigliata. La seconda versione più recente è attualmente la versione Redis 5.0 (impostazione predefinita della console: 6.x)
Tenendo presente queste impostazioni, la sezione successiva ti guiderà nella creazione dell'istanza dalla console Cloud. Se preferisci farlo dalla riga di comando, vai avanti.
Dalla console Cloud
Vai alla pagina Cloud Memorystore nella console Cloud (potrebbe esserti chiesto di inserire i dati di fatturazione). Se non hai ancora attivato Memorystore, ti verrà chiesto di farlo:

Una volta attivato (e possibilmente insieme alla fatturazione), si aprirà la dashboard di Memorystore. Qui puoi visualizzare tutte le istanze create nel tuo progetto. Il progetto mostrato di seguito non ne ha, quindi è per questo che vedi "Nessuna riga da visualizzare". Per creare un'istanza Memorystore, fai clic su Crea istanza in alto:

Questa pagina include un modulo da compilare con le impostazioni desiderate per creare l'istanza Memorystore:

Per contenere i costi di questo tutorial e della relativa app di esempio, segui i consigli illustrati in precedenza. Dopo aver effettuato le selezioni, fai clic su Crea. Il processo di creazione richiede diversi minuti. Al termine, copia l'indirizzo IP e il numero di porta dell'istanza da aggiungere a app.yaml.
Dalla riga di comando
Sebbene la creazione di istanze Memorystore da Cloud Console sia visivamente informativa, alcuni preferiscono la riga di comando. Prima di procedere, assicurati di aver installato e inizializzato gcloud.
Come per la console Cloud, Cloud Memorystore for Redis deve essere abilitato. Esegui il comando gcloud services enable redis.googleapis.com e attendi il completamento, come in questo esempio:
$ gcloud services enable redis.googleapis.com Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Se il servizio è già stato attivato, l'esecuzione (di nuovo) del comando non ha effetti collaterali (negativi). Con il servizio abilitato, creiamo un'istanza Memorystore. Il comando è il seguente:
gcloud redis instances create NAME --redis-version VERSION \
--region REGION --project PROJECT_ID
Scegli un nome per la tua istanza Memorystore. Questo lab utilizza "demo-ms" come nome e "my-project" come ID progetto. La regione di questa app di esempio è us-central1 (la stessa di us-central), ma puoi utilizzarne una più vicina a te se la latenza è un problema. Devi selezionare la stessa regione dell'app App Engine. Puoi selezionare la versione di Redis che preferisci, ma stiamo utilizzando la versione 5 come consigliato in precedenza. Date queste impostazioni, questo è il comando da eseguire (insieme all'output associato):
$ gcloud redis instances create demo-ms --region us-central1 \
--redis-version redis_5_0 --project my-project
Create request issued for: [demo-ms]
Waiting for operation [projects/my-project/locations/us-central1/operations/operation-xxxx] to complete...done.
Created instance [demo-ms].
A differenza delle impostazioni predefinite della console Cloud, gcloud utilizza risorse minime per impostazione predefinita. Il risultato è che né il livello di servizio né la quantità di spazio di archiviazione erano richiesti in questo comando. La creazione di un'istanza Memorystore richiede diversi minuti. Al termine, annotati l'indirizzo IP e il numero di porta dell'istanza, in quanto verranno aggiunti a app.yaml a breve.
Conferma la creazione dell'istanza
Dalla console Cloud o dalla riga di comando
Indipendentemente dal fatto che tu abbia creato l'istanza dalla console Cloud o dalla riga di comando, puoi verificare che sia disponibile e pronta per l'uso con questo comando: gcloud redis instances list --region REGION
Ecco il comando per controllare le istanze nella regione us-central1 insieme all'output previsto che mostra l'istanza appena creata:
$ gcloud redis instances list --region us-central1 INSTANCE_NAME VERSION REGION TIER SIZE_GB HOST PORT NETWORK RESERVED_IP STATUS CREATE_TIME demo-ms REDIS_5_0 us-central1 BASIC 1 10.aa.bb.cc 6379 default 10.aa.bb.dd/29 READY 2022-01-28T09:24:45
Quando ti viene chiesto di inserire le informazioni sull'istanza o di configurare l'app, assicurati di utilizzare HOST e PORT (non RESERVED_IP). La dashboard di Cloud Memorystore in Cloud Console dovrebbe ora mostrare l'istanza:

Dalla macchina virtuale Compute Engine
Se hai una macchina virtuale (VM) Compute Engine, puoi anche inviare comandi diretti all'istanza Memorystore da una VM per verificare che funzioni. Tieni presente che l'utilizzo di una VM potrebbe comportare costi associati indipendenti dalle risorse che stai già utilizzando.
Crea un connettore di accesso VPC serverless
Come per Cloud Memorystore, puoi creare il connettore VPC serverless in Cloud Console o dalla riga di comando. Allo stesso modo, Cloud VPC non ha un livello senza costi, pertanto ti consigliamo di allocare la quantità minima di risorse per completare il codelab al fine di ridurre al minimo i costi. Questo risultato può essere ottenuto con le seguenti impostazioni:
- Seleziona il numero massimo di istanze più basso: 3 (valore predefinito di console e
gcloud: 10) - Scegli il tipo di macchina meno costoso:
f1-micro(impostazione predefinita della console:e2-micro, nessuna impostazione predefinita pergcloud)
La sezione successiva ti guiderà nella creazione del connettore dalla console Cloud utilizzando le impostazioni VPC Cloud riportate sopra. Se preferisci farlo dalla riga di comando, vai alla sezione successiva.
Dalla console Cloud
Vai alla pagina "Accesso VPC serverless" di Cloud Networking nella console Cloud (potrebbe esserti chiesto di inserire i dati di fatturazione). Se non hai ancora abilitato l'API, ti verrà chiesto di farlo:

Una volta abilitata l'API (e possibilmente la fatturazione), visualizzerai la dashboard con tutti i connettori VPC creati. Il progetto utilizzato nello screenshot riportato di seguito non ne ha, perciò viene visualizzato il messaggio "Nessuna riga da visualizzare". Nella console, fai clic su Crea connettore in alto:

Compila il modulo con le impostazioni desiderate:

Scegli le impostazioni appropriate per le tue applicazioni. Per questo tutorial e la sua app di esempio con esigenze minime, è opportuno ridurre al minimo i costi, quindi segui i consigli trattati in precedenza. Dopo aver effettuato le selezioni, fai clic su Crea. Il provisioning di un connettore VPC richiede alcuni minuti.
Dalla riga di comando
Prima di creare un connettore VPC, abilita l'API Serverless VPC Access. Dovresti vedere un output simile dopo aver eseguito il seguente comando:
$ gcloud services enable vpcaccess.googleapis.com Operation "operations/acf.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Con l'API abilitata, viene creato un connettore VPC con un comando simile al seguente:
gcloud compute networks vpc-access connectors create CONNECTOR_NAME \
--range 10.8.0.0/28 --region REGION --project PROJECT_ID
Scegli un nome per il connettore e un indirizzo IP iniziale del blocco CIDR /28 inutilizzato. Questo tutorial si basa sulle seguenti ipotesi:
- ID progetto:
my-project - Nome connettore VPC:
demo-vpc - Istanze minime: 2 (valore predefinito) e istanze massime: 3
- Tipo di istanza:
f1-micro - Regione:
us-central1 - Blocco CIDR IPv4:
10.8.0.0/28(come consigliato nella console cloud)
Se esegui il seguente comando tenendo presente le ipotesi precedenti, l'output dovrebbe essere simile a quello riportato di seguito:
$ gcloud compute networks vpc-access connectors create demo-vpc \
--max-instances 3 --range 10.8.0.0/28 --machine-type f1-micro \
--region us-central1 --project my-project
Create request issued for: [demo-vpc]
Waiting for operation [projects/my-project/locations/us-central1/operations/xxx] to complete...done.
Created connector [demo-vpc].
Il comando precedente omette la specifica dei valori predefiniti, ad esempio un numero minimo di istanze pari a 2 e una rete denominata default. La creazione di un connettore VPC richiede alcuni minuti.
Conferma la creazione del connettore
Al termine della procedura, esegui il seguente comando gcloud, supponendo che si tratti della regione us-central1, per confermare che sia stato creato e pronto per l'uso:
$ gcloud compute networks vpc-access connectors list --region us-central1 CONNECTOR_ID REGION NETWORK IP_CIDR_RANGE SUBNET SUBNET_PROJECT MIN_THROUGHPUT MAX_THROUGHPUT STATE demo-vpc us-central1 default 10.8.0.0/28 200 300 READY
Analogamente, la dashboard ora dovrebbe mostrare il connettore appena creato:

Prendi nota dell'ID progetto Cloud, del nome del connettore VPC e della regione.
Ora che hai creato le risorse Cloud aggiuntive necessarie, tramite la riga di comando o nella console, è il momento di aggiornare la configurazione dell'applicazione per supportarne l'utilizzo.
5. Aggiorna i file di configurazione
Il primo passaggio consiste nell'apportare tutti gli aggiornamenti necessari ai file di configurazione. L'obiettivo principale di questo codelab è aiutare gli utenti di Python 2 a eseguire la migrazione. Tuttavia, in ogni sezione riportata di seguito, i contenuti vengono solitamente seguiti da informazioni sul porting a Python 3.
requirements.txt
In questa sezione, aggiungiamo pacchetti per supportare Cloud Memorystore e Cloud NDB. Per Cloud Memorystore for Redis, è sufficiente utilizzare il client Redis standard per Python (redis), poiché non esiste una libreria client Cloud Memorystore in sé. Aggiungi sia redis che google-cloud-ndb a requirements.txt, unendo flask del Modulo 12:
flask
redis
google-cloud-ndb
Questo file requirements.txt non include numeri di versione, il che significa che sono selezionate le versioni più recenti. Se si verificano incompatibilità, specifica i numeri di versione per bloccare le versioni funzionanti.
app.yaml
Nuove sezioni da aggiungere
Il runtime Python 2 di App Engine richiede pacchetti di terze parti specifici quando si utilizzano le API Cloud come Cloud NDB, ovvero grpcio e setuptools. Gli utenti di Python 2 devono elencare le librerie integrate come queste insieme a una versione disponibile in app.yaml. Se non hai ancora una sezione libraries, creane una e aggiungi entrambe le librerie come segue:
libraries:
- name: grpcio
version: latest
- name: setuptools
version: latest
Quando esegui la migrazione della tua app, potrebbe già avere una sezione libraries. Se è così e mancano sia grpcio che setuptools, aggiungili alla sezione libraries esistente.
Successivamente, la nostra app di esempio ha bisogno delle informazioni sull'istanza Cloud Memorystore e sul connettore VPC, quindi aggiungi le due nuove sezioni seguenti a app.yaml indipendentemente dal runtime Python che utilizzi:
env_variables:
REDIS_HOST: 'YOUR_REDIS_HOST'
REDIS_PORT: 'YOUR_REDIS_PORT'
vpc_access_connector:
name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR
Per quanto riguarda gli aggiornamenti obbligatori, è tutto. Il tuo app.yaml aggiornato dovrebbe ora avere questo aspetto:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
env_variables:
REDIS_HOST: 'YOUR_REDIS_HOST'
REDIS_PORT: 'YOUR_REDIS_PORT'
vpc_access_connector:
name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR
Di seguito è riportato un "prima e dopo" che illustra gli aggiornamenti da applicare a app.yaml:

*Differenze di Python 3
Questa sezione è facoltativa e solo se esegui il porting a Python 3. Per farlo, devi apportare una serie di modifiche alla configurazione di Python 2. Salta questa sezione se al momento non esegui l'upgrade.
Né threadsafe né api_version vengono utilizzati per il runtime Python 3, quindi elimina entrambe le impostazioni. L'ultimo runtime di App Engine non supporta le librerie di terze parti integrate né la copia di librerie non integrate. L'unico requisito per i pacchetti di terze parti è elencarli in requirements.txt. Di conseguenza, l'intera sezione libraries di app.yaml può essere eliminata.
Successivamente, il runtime Python 3 richiede l'utilizzo di framework web che eseguono il proprio routing, motivo per cui abbiamo mostrato agli sviluppatori come eseguire la migrazione da webp2 a Flask nel Modulo 1. Di conseguenza, tutti i gestori di script devono essere modificati in auto. Poiché questa app non gestisce file statici, è "inutile" avere gestori elencati (poiché sono tutti auto), quindi è possibile rimuovere anche l'intera sezione handlers. Di conseguenza, il nuovo app.yaml abbreviato e modificato per Python 3 dovrebbe essere abbreviato in questo modo:
runtime: python39
env_variables:
REDIS_HOST: 'YOUR_REDIS_HOST'
REDIS_PORT: 'YOUR_REDIS_PORT'
vpc_access_connector:
name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR
Riepilogo delle differenze in app.yaml durante il porting a Python 3:
- Eliminare le impostazioni di
threadsafeeapi_version - Elimina la sezione
libraries - Elimina la sezione
handlers(o solo i gestoriscriptse la tua app pubblica file statici)
Sostituisci i valori
I valori nelle nuove sezioni per Memorystore e il connettore VPC sono solo segnaposto. Sostituisci i valori in maiuscolo (YOUR_REDIS_HOST, YOUR_REDIS_PORT, PROJECT_ID, REGION, CONNECTOR_NAME) con i valori salvati quando hai creato queste risorse in precedenza. Per quanto riguarda l'istanza Memorystore, assicurati di utilizzare HOST (non RESERVED_IP) e PORT. Ecco un modo rapido da riga di comando per ottenere HOST e PORT, supponendo che il nome dell'istanza sia demo-ms e che REGION sia us-central1:
$ gcloud redis instances describe demo-ms --region us-central1 \
--format "value(host,port)"
10.251.161.51 6379
Se l'indirizzo IP della nostra istanza Redis di esempio era 10.10.10.10 utilizzando la porta 6379 nel nostro progetto my-project situato nella regione us-central1 con un nome di connettore VPC demo-vpc, queste sezioni in app.yaml avranno il seguente aspetto:
env_variables:
REDIS_HOST: '10.10.10.10'
REDIS_PORT: '6379'
vpc_access_connector:
name: projects/my-project/locations/us-central1/connectors/demo-vpc
Crea o aggiorna appengine_config.py
Aggiungere il supporto per le librerie di terze parti integrate
Proprio come abbiamo fatto in precedenza con app.yaml, aggiungi l'utilizzo delle librerie grpcio e setuptools. Modifica appengine_config.py per supportare le librerie di terze parti integrate. Se ti sembra familiare, è perché era necessario anche nel modulo 2 durante la migrazione da App Engine ndb a Cloud NDB. La modifica esatta richiesta consiste nell'aggiungere la cartella lib al working set setuptools.pkg_resources:

*Differenze di Python 3
Questa sezione è facoltativa e solo se esegui il porting a Python 3. Una delle modifiche di benvenuto di App Engine di seconda generazione è che la copia (a volte chiamata "vendoring") di pacchetti di terze parti (non integrati) e il riferimento a pacchetti di terze parti integrati in app.yaml non sono più necessari, il che significa che puoi eliminare l'intero file appengine_config.py.
6. Aggiorna i file dell'applicazione
Esiste un solo file dell'applicazione, main.py, quindi tutte le modifiche in questa sezione interessano solo questo file. Abbiamo fornito una rappresentazione illustrata delle modifiche che apporteremo per eseguire la migrazione di questa applicazione a Cloud Memorystore. È solo a scopo illustrativo e non è pensato per essere analizzato nel dettaglio. Tutto il lavoro è nelle modifiche che apportiamo al codice.

Affrontiamo queste sezioni una alla volta, partendo dall'alto.
Aggiorna importazioni
La sezione di importazione in main.py per il modulo 12 utilizza Cloud NDB e Cloud Tasks. Ecco le relative importazioni:
PRIMA:
from flask import Flask, render_template, request
from google.appengine.api import memcache
from google.appengine.ext import ndb
Il passaggio a Memorystore richiede la lettura delle variabili di ambiente, il che significa che abbiamo bisogno del modulo Python os e di redis, il client Python Redis. Poiché Redis non può memorizzare nella cache gli oggetti Python, esegui il marshalling dell'elenco delle visite più recenti utilizzando pickle, quindi importalo. Un vantaggio di Memcache è che la serializzazione degli oggetti avviene automaticamente, mentre Memorystore è un po' più "fai da te". Infine, esegui l'upgrade da App Engine ndb a Cloud NDB sostituendo google.appengine.ext.ndb con google.cloud.ndb. Dopo queste modifiche, le importazioni dovrebbero avere il seguente aspetto:
DOPO:
import os
import pickle
from flask import Flask, render_template, request
from google.cloud import ndb
import redis
Aggiornamento inizializzazione
L'inizializzazione del modulo 12 consiste nell'istanziamento dell'oggetto applicazione Flask app e nell'impostazione di una costante per un'ora di memorizzazione nella cache:
PRIMA:
app = Flask(__name__)
HOUR = 3600
L'utilizzo delle API Cloud richiede un client, quindi crea un'istanza di un client Cloud NDB subito dopo Flask. Successivamente, recupera l'indirizzo IP e il numero di porta dell'istanza Memorystore dalle variabili di ambiente impostate in app.yaml. Con queste informazioni, crea un'istanza di un client Redis. Ecco come appare il codice dopo questi aggiornamenti:
DOPO:
app = Flask(__name__)
ds_client = ndb.Client()
HOUR = 3600
REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
REDIS_PORT = os.environ.get('REDIS_PORT', '6379')
REDIS = redis.Redis(host=REDIS_HOST, port=REDIS_PORT)
*Migrazione a Python 3
Questa sezione è facoltativa se inizi dalla versione Python 3 dell'app del modulo 12. In questo caso, sono necessarie diverse modifiche relative a importazioni e inizializzazione.
Innanzitutto, poiché Memcache è un servizio in bundle di App Engine, il suo utilizzo in un'app Python 3 richiede l'SDK App Engine, in particolare il wrapping dell'applicazione WSGI (nonché altre configurazioni necessarie):
PRIMA:
from flask import Flask, render_template, request
from google.appengine.api import memcache, wrap_wsgi_app
from google.appengine.ext import ndb
app = Flask(__name__)
app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
HOUR = 3600
Poiché stiamo eseguendo la migrazione a Cloud Memorystore (non un servizio integrato di App Engine come Memcache), l'utilizzo dell'SDK deve essere rimosso. È semplice, basta eliminare l'intera riga che importa sia memcache che wrap_wsgi_app. Elimina anche la riga che chiama wrap_wsgi_app(). Questi aggiornamenti lasciano questa parte dell'app (in realtà, l'intera app) identica alla versione Python 2.
DOPO:
import os
import pickle
from flask import Flask, render_template, request
from google.cloud import ndb
import redis
app = Flask(__name__)
ds_client = ndb.Client()
HOUR = 3600
REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
REDIS_PORT = os.environ.get('REDIS_PORT', '6379')
REDIS = redis.Redis(host=REDIS_HOST, port=REDIS_PORT)
Infine, rimuovi l'utilizzo dell'SDK da app.yaml (elimina la riga: app_engine_apis: true) e requirements.txt (elimina la riga: appengine-python-standard).
Migrazione a Cloud Memorystore (e Cloud NDB)
Il modello dei dati di Cloud NDB è progettato per essere compatibile con ndb di App Engine, il che significa che la definizione degli oggetti Visit rimane invariata. Come nella migrazione del modulo 2 a Cloud NDB, tutte le chiamate Datastore in store_visit() e fetch_visits() vengono aumentate e incorporate in un nuovo blocco with (poiché è necessario l'utilizzo del gestore di contesto Cloud NDB). Ecco le chiamate prima di questa modifica:
PRIMA:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
Aggiungi un blocco with ds_client.context() a entrambe le funzioni e inserisci le chiamate Datastore all'interno (con rientro). In questo caso, non sono necessarie modifiche alle chiamate:
DOPO:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return Visit.query().order(-Visit.timestamp).fetch(limit)
Successivamente, esaminiamo le modifiche alla memorizzazione nella cache. Ecco la funzione main() del modulo 12:
PRIMA:
@app.route('/')
def root():
'main application (GET) handler'
# check for (hour-)cached visits
ip_addr, usr_agt = request.remote_addr, request.user_agent
visitor = '{}: {}'.format(ip_addr, usr_agt)
visits = memcache.get('visits')
# register visit & run DB query if cache empty or new visitor
if not visits or visits[0].visitor != visitor:
store_visit(ip_addr, usr_agt)
visits = list(fetch_visits(10))
memcache.set('visits', visits, HOUR) # set() not add()
return render_template('index.html', visits=visits)
Redis ha chiamate "get" e "set", proprio come Memcache. Tutto ciò che facciamo è scambiare le rispettive librerie client, giusto? Quasi. Come accennato in precedenza, non possiamo memorizzare nella cache un elenco Python con Redis (perché deve essere prima serializzato, cosa che Memcache fa automaticamente), quindi nella chiamata set(), "pickle" le visite in una stringa con pickle.dumps(). Allo stesso modo, quando recuperi le visite dalla cache, devi decomprimere il file con pickle.loads() subito dopo get(). Ecco l'handler principale dopo l'implementazione di queste modifiche:
DOPO:
@app.route('/')
def root():
'main application (GET) handler'
# check for (hour-)cached visits
ip_addr, usr_agt = request.remote_addr, request.user_agent
visitor = '{}: {}'.format(ip_addr, usr_agt)
rsp = REDIS.get('visits')
visits = pickle.loads(rsp) if rsp else None
# register visit & run DB query if cache empty or new visitor
if not visits or visits[0].visitor != visitor:
store_visit(ip_addr, usr_agt)
visits = list(fetch_visits(10))
REDIS.set('visits', pickle.dumps(visits), ex=HOUR)
return render_template('index.html', visits=visits)
Con questo si concludono le modifiche necessarie in main.py per convertire l'utilizzo di Memcache nell'app di esempio in Cloud Memorystore. Che ne dici del modello HTML e del porting a Python 3?
Aggiornare il file modello HTML e portarlo a Python 3?
Sorpresa! Non devi fare nulla, perché l'applicazione è stata progettata per essere eseguita sia su Python 2 sia su Python 3 senza modifiche al codice né librerie di compatibilità. Troverai main.py. identici nelle cartelle "FINISH" di mod13a (2.x) e mod13b (3.x). Lo stesso vale per requirements.txt , a parte eventuali differenze nei numeri di versione (se utilizzati). Poiché l'interfaccia utente rimane invariata, non sono previsti aggiornamenti neanche per templates/index.html.
Tutto il necessario per eseguire questa app su Python 3 App Engine è stato completato in precedenza nella configurazione: le direttive non necessarie sono state rimosse da app.yaml e sia appengine_config.py sia la cartella lib sono stati eliminati perché non vengono utilizzati in Python 3.
7. Riepilogo/Pulizia
Questa sezione conclude il codelab eseguendo il deployment dell'app, verificando che funzioni come previsto e in qualsiasi output riflesso. Dopo la convalida dell'app, esegui la pulizia e valuta i passaggi successivi.
Esegui il deployment e verifica l'applicazione
L'ultimo controllo consiste sempre nell'eseguire il deployment dell'app di esempio. Sviluppatori Python 2: elimina e reinstalla lib con i comandi riportati di seguito. Se sul sistema sono installati sia Python 2 che 3, potrebbe essere necessario eseguire esplicitamente pip2.
rm -rf ./lib pip install -t lib -r requirements.txt
Ora gli sviluppatori di Python 2 e 3 devono eseguire il deployment delle loro app con:
gcloud app deploy
Poiché hai semplicemente modificato la struttura interna per un servizio di memorizzazione nella cache completamente diverso, l'app dovrebbe funzionare in modo identico all'app del modulo 12:

Questo passaggio completa il codelab. Ti invitiamo a confrontare l'app di esempio aggiornata con una delle cartelle del modulo 13, mod13a (Python 2) o mod13b (Python 3).
Esegui la pulizia
Generale
Se hai finito per il momento, ti consigliamo di disattivare l'app App Engine per evitare addebiti. Tuttavia, se vuoi fare altri test o esperimenti, la piattaforma App Engine ha una quota senza costi e, finché non superi questo livello di utilizzo, non ti verranno addebitati costi. Questo vale per il calcolo, ma potrebbero essere addebitati anche costi per i servizi App Engine pertinenti, quindi consulta la pagina dei prezzi per ulteriori informazioni. Se questa migrazione coinvolge altri servizi cloud, questi vengono fatturati separatamente. In entrambi i casi, se applicabile, consulta la sezione "Specifiche per questo codelab" di seguito.
Per una divulgazione completa, il deployment su una piattaforma di calcolo serverless di Google Cloud come App Engine comporta costi di build e archiviazione minimi. Cloud Build ha una propria quota senza costi, così come Cloud Storage. L'archiviazione di questa immagine utilizza parte della quota. Tuttavia, potresti vivere in una regione che non dispone di un livello senza costi, quindi tieni sotto controllo l'utilizzo dello spazio di archiviazione per ridurre al minimo i potenziali costi. Le "cartelle" Cloud Storage specifiche che devi esaminare includono:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- I link di archiviazione riportati sopra dipendono dalla tua
PROJECT_IDe dalla tua *LOC*, ad esempio "us" se la tua app è ospitata negli Stati Uniti.
D'altra parte, se non intendi continuare con questa applicazione o con altri codelab di migrazione correlati e vuoi eliminare tutto completamente, chiudi il progetto.
Specifico per questo codelab
I servizi elencati di seguito sono univoci per questo codelab. Per saperne di più, consulta la documentazione di ogni prodotto:
- Cloud Memorystore richiede istanze e non ha un livello senza costi. Per saperne di più sui costi di utilizzo, consulta la pagina dei prezzi.
- I connettori di accesso VPC serverless di Cloud richiedono istanze e non hanno un livello senza costi. Per saperne di più sui costi di utilizzo, consulta la sezione dedicata nella pagina dei prezzi di Cloud VPC.
- Cloud Datastore (Cloud Firestore in modalità Datastore) ha un livello senza costi; per saperne di più, consulta la pagina dei prezzi.
Questo tutorial ha comportato l'utilizzo di quattro prodotti Cloud:
- App Engine
- Cloud Datastore
- Cloud Memorystore
- Cloud VPC
Di seguito sono riportate le istruzioni per rilasciare queste risorse ed evitare/ridurre al minimo gli addebiti.
Arresta l'istanza Memorystore e il connettore VPC
Questi sono i prodotti senza un livello senza costi, quindi stai sostenendo costi di fatturazione in questo momento. Se non chiudi il progetto Cloud (vedi la sezione successiva), devi eliminare sia l'istanza Memorystore sia il connettore VPC per interrompere la fatturazione. Come quando hai creato queste risorse, puoi rilasciarle dalla console Cloud o dalla riga di comando.
Dalla console Cloud
Per eliminare l'istanza Memorystore, torna alla dashboard Memorystore e fai clic sull'ID istanza:

Una volta visualizzata la pagina dei dettagli dell'istanza, fai clic su "Elimina" e conferma:
Per eliminare il connettore VPC, vai alla relativa dashboard, seleziona la casella di controllo accanto al connettore che vuoi eliminare, quindi fai clic su "Elimina" e conferma:

Dalla riga di comando
La seguente coppia di comandi gcloud elimina rispettivamente l'istanza Memorystore e il connettore VPC:
gcloud redis instances delete INSTANCE --region REGIONgcloud compute networks vpc-access connectors delete CONNECTOR --region REGION
Se non hai impostato l'ID progetto con gcloud config set project, potresti dover fornire --project PROJECT_ID. Se la tua istanza Memorystore si chiama demo-ms e il connettore VPC si chiama demo-vpc ed entrambi si trovano nella regione us-central1, esegui la seguente coppia di comandi e conferma:
$ gcloud redis instances delete demo-ms --region us-central1 You are about to delete instance [demo-ms] in [us-central1]. Any associated data will be lost. Do you want to continue (Y/n)? Delete request issued for: [demo-ms] Waiting for operation [projects/PROJECT/locations/REGION/operations/operation-aaaaa-bbbbb-ccccc-ddddd] to complete...done. Deleted instance [demo-ms]. $ $ gcloud compute networks vpc-access connectors delete demo-vpc --region us-central1 You are about to delete connector [demo-vpc] in [us-central1]. Any associated data will be lost. Do you want to continue (Y/n)? Delete request issued for: [demo-vpc] Waiting for operation [projects/PROJECT/locations/REGION/operations/aaaaa-bbbb-cccc-dddd-eeeee] to complete...done. Deleted connector [demo-vpc].
L'esecuzione di ogni richiesta richiede alcuni minuti. Questi passaggi sono facoltativi se scegli di chiudere l'intero progetto Cloud come descritto in precedenza, ma continuerai a ricevere fatture finché il processo di chiusura non sarà completato.
Passaggi successivi
Oltre a questo tutorial, altri moduli di migrazione che si concentrano sul passaggio dai servizi in bundle legacy da prendere in considerazione includono:
- Modulo 2: esegui la migrazione da App Engine
ndba Cloud NDB - Moduli 7-9: esegui la migrazione delle attività push di App Engine Task Queue a Cloud Tasks
- Moduli 12-13: esegui la migrazione da Memcache App Engine a Cloud Memorystore
- Moduli 15-16: esegui la migrazione da App Engine Blobstore a Cloud Storage
- Moduli 18-19: esegui la migrazione dalla coda di attività App Engine (attività pull) a Cloud Pub/Sub
App Engine non è più l'unica piattaforma serverless in Google Cloud. Se hai una piccola app App Engine o una con funzionalità limitate e vuoi trasformarla in un microservizio autonomo oppure vuoi suddividere un'app monolitica in più componenti riutilizzabili, questi sono buoni motivi per prendere in considerazione il passaggio a Cloud Functions. Se la containerizzazione è diventata parte del flusso di lavoro di sviluppo delle applicazioni, in particolare se consiste in una pipeline CI/CD (integrazione continua/distribuzione continua o deployment continuo), valuta la migrazione a Cloud Run. Questi scenari sono trattati nei seguenti moduli:
- Esegui la migrazione da App Engine a Cloud Functions: consulta il modulo 11
- Esegui la migrazione da App Engine a Cloud Run: consulta il modulo 4 per inserire la tua app in un container con Docker o il modulo 5 per farlo senza container, conoscenze di Docker o
Dockerfiles
Il passaggio a un'altra piattaforma serverless è facoltativo e ti consigliamo di valutare le opzioni migliori per le tue app e i tuoi casi d'uso prima di apportare modifiche.
Indipendentemente dal modulo di migrazione che prenderai in considerazione, tutti i contenuti di Serverless Migration Station (codelab, video, codice sorgente [se disponibile]) sono accessibili nel relativo repository open source. Il repository README fornisce anche indicazioni sulle migrazioni da prendere in considerazione e sull'eventuale "ordine" dei moduli di migrazione pertinenti.
8. Risorse aggiuntive
Di seguito sono elencate risorse aggiuntive per gli sviluppatori che vogliono esplorare ulteriormente questo modulo di migrazione o quelli correlati, nonché i prodotti correlati. Sono inclusi i luoghi in cui fornire feedback su questi contenuti, i link al codice e vari documenti che potresti trovare utili.
Problemi/feedback relativi a Codelab
Se riscontri problemi con questo codelab, cerca prima il tuo problema prima di presentare una segnalazione. Link per cercare e creare nuovi problemi:
Risorse per la migrazione
I link alle cartelle del repository per il modulo 12 (INIZIO) e il modulo 13 (FINE) sono riportati nella tabella di seguito. Puoi accedervi anche dal repository per tutte le migrazioni dei codelab di App Engine, che puoi clonare o scaricare come file ZIP.
Codelab | Python 2 | Python 3 |
Modulo 13 (questo codelab) |
Riferimenti online
Di seguito sono riportate risorse online che potrebbero essere pertinenti per questo tutorial:
App Engine
- Documentazione di App Engine
- Runtime Python 2 App Engine (ambiente standard)
- Utilizzo delle librerie integrate di App Engine su Python 2 App Engine
- Runtime Python 3 App Engine (ambiente standard)
- Differenze tra i runtime di Python 2 e 3 di App Engine (ambiente standard)
- Guida alla migrazione da Python 2 a 3 di App Engine (ambiente standard)
- Informazioni su prezzi e quote di App Engine
App Engine NDB e Cloud NDB
- Panoramica di App Engine NDB
- Utilizzo di App Engine NDB Datastore
- Documenti NDB di Google Cloud
- Repository Google Cloud NDB
- Informazioni sui prezzi di Cloud Datastore
Memcache App Engine e Cloud Memorystore
- Panoramica di Memcache App Engine
- Riferimento
memcachedi Python 2 App Engine - Riferimento
memcachedi Python 3 App Engine - Guida alla migrazione da App Engine
memcachea Cloud Memorystore - Documentazione di Cloud Memorystore
- Documentazione di Cloud Memorystore for Redis
- Informazioni sui prezzi di Cloud Memorystore for Redis
- Versioni di Redis supportate da Cloud Memorystore
- Home page di Cloud Memorystore
- Crea una nuova istanza Memorystore in Cloud Console
- Home page del client Python Redis
- Documentazione della libreria client Redis per Python
Cloud VPC
- Documenti VPC di Google Cloud
- Home page di Google Cloud VPC
- Informazioni sui prezzi di Cloud VPC
- Crea un nuovo connettore di accesso VPC serverless nella console Cloud
Altre informazioni sul cloud
- Python su Google Cloud Platform
- Librerie client Python di Google Cloud
- Livello "Sempre senza costi" di Google Cloud
- Google Cloud SDK (strumento a riga di comando
gcloud) - Tutta la documentazione di Google Cloud
Licenza
Questo lavoro è concesso in licenza ai sensi di una licenza Creative Commons Attribution 2.0 Generic.
