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 dalle attività pull della coda di attività di App Engine a Cloud Pub/Sub. Esiste anche una migrazione implicita da App Engine NDB a Cloud NDB per l'accesso a Datastore (principalmente trattata nel modulo 2), nonché un upgrade a Python 3.
Nel modulo 18, imparerai ad aggiungere l'utilizzo delle attività di pull nella tua app. In questo modulo, prenderai l'app del modulo 18 completata e ne eseguirai la migrazione a Cloud Pub/Sub. Gli utenti che utilizzano le code di attività per le attività push eseguiranno invece la migrazione a Cloud Tasks e dovranno fare riferimento ai moduli 7-9.
Imparerai a utilizzare
- Sostituisci l'utilizzo di App Engine Task Queue (attività pull) con Cloud Pub/Sub
- Sostituisci l'utilizzo di App Engine NDB con Cloud NDB (vedi anche il modulo 2)
- Porta l'app a Python 3
Che cosa ti serve
- Un progetto Google Cloud Platform con un account di fatturazione GCP attivo.
- 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 di esempio di App Engine del modulo 18 funzionante
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
App Engine Task Queue supporta le attività push e pull. Per migliorare la portabilità delle applicazioni, Google Cloud consiglia di eseguire la migrazione dai servizi integrati legacy come Task Queue ad altri servizi autonomi di Cloud o equivalenti di terze parti.
- Gli utenti delle code di attività push devono eseguire la migrazione a Cloud Tasks.
- Gli utenti delle code di attività pull devono eseguire la migrazione a Cloud Pub/Sub.
I moduli 7-9 trattano la migrazione delle attività push, mentre i moduli 18-19 si concentrano sulla migrazione delle attività pull. Anche se Cloud Tasks corrisponde più da vicino alle attività push di Task Queues, Pub/Sub non è un analogo altrettanto vicino alle attività pull di Task Queues.
Pub/Sub offre più funzionalità rispetto alla funzionalità pull fornita da Task Queue. Ad esempio, Pub/Sub dispone anche della funzionalità push, ma Cloud Tasks è più simile alle attività push di Task Queue, quindi il push di Pub/Sub non è coperto da nessuno dei moduli di migrazione. Questo codelab del modulo 19 mostra il passaggio dal meccanismo di gestione delle code dalle code pull di Task Queue a Pub/Sub, nonché la migrazione da App Engine NDB a Cloud NDB per l'accesso a Datastore, ripetendo la migrazione del modulo 2.
Sebbene il codice del modulo 18 sia "pubblicizzato" come app di esempio Python 2, l'origine stessa è compatibile con Python 2 e 3 e rimane tale anche dopo la migrazione a Cloud Pub/Sub (e Cloud NDB) nel modulo 19.
Questo tutorial prevede i seguenti passaggi:
- Configurazione/preparazione
- Aggiorna configurazione
- Modificare il codice dell'applicazione
3. Configurazione/preparazione
Questa sezione spiega come:
- Configura il progetto cloud
- Ottieni l'app di esempio di base
- (R)esegui il deployment e convalida l'app di riferimento
- Abilitare nuovi servizi/API Google Cloud
Questi passaggi assicurano che tu stia iniziando con un codice funzionante e che sia pronto per la migrazione ai servizi cloud.
1. Configura il progetto
Se hai completato il codelab del modulo 18, riutilizza lo stesso progetto (e codice). In alternativa, crea un nuovo progetto o riutilizza un altro progetto esistente. Assicurati che il progetto abbia un account di fatturazione attivo e un'app App Engine abilitata. Trova l'ID progetto, in quanto ti servirà durante questo codelab. Utilizzalo ogni volta che incontri la variabile PROJECT_ID.
2. Ottieni l'app di esempio di base
Uno dei prerequisiti è un'app App Engine del modulo 18 funzionante, quindi completa il relativo codelab (consigliato; link sopra) o copia il codice del modulo 18 dal repository. Che tu utilizzi il tuo o il nostro, è qui che inizieremo ("INIZIO"). Questo codelab ti guida nella migrazione e si conclude con un codice simile a quello presente nella cartella del repository del modulo 19 ("FINISH").
- INIZIO: Cartella del modulo 18 (Python 2)
- FINE: Cartella Modulo 19 (Python 2 e 3)
- Intero repository (per clonare o scaricare il file ZIP)
Indipendentemente dall'app del Modulo 18 che utilizzi, la cartella dovrebbe essere simile a quella riportata di seguito, possibilmente con anche una cartella lib:
$ ls README.md appengine_config.py queue.yaml templates app.yaml main.py requirements.txt
3. (R)esegui il deployment e convalida l'app di riferimento
Esegui i seguenti passaggi per eseguire il deployment dell'app Modulo 18:
- Elimina la cartella
lib, se presente, ed eseguipip install -t lib -r requirements.txtper ripopolarelib. Potresti dover utilizzarepip2se hai installato sia Python 2 che 3 sulla tua macchina di sviluppo. - Assicurati di aver installato e inizializzato lo strumento a riga di comando
gcloude di averne esaminato l'utilizzo. - (Facoltativo) Imposta il tuo progetto cloud con
gcloud config set projectPROJECT_IDse non vuoi inserirePROJECT_IDcon ogni comandogcloudche emetti. - Esegui il deployment dell'app di esempio con
gcloud app deploy - Verifica che l'app funzioni come previsto senza problemi. Se hai completato il codelab del modulo 18, l'app mostra i principali visitatori insieme alle visite più recenti (come illustrato di seguito). In caso contrario, potrebbero non essere disponibili conteggi delle visite da visualizzare.

Prima di eseguire la migrazione dell'app di esempio del modulo 18, devi prima abilitare i servizi cloud che verranno utilizzati dall'app modificata.
4. Abilitare nuovi servizi/API Google Cloud
La vecchia app utilizzava i servizi in bundle di App Engine, che non richiedono configurazione aggiuntiva, ma i servizi Cloud autonomi sì. L'app aggiornata utilizzerà sia Cloud Pub/Sub sia Cloud Datastore (tramite la libreria client Cloud NDB). App Engine e entrambe le API Cloud hanno quote del livello "Sempre senza costi" e, finché rispetti questi limiti, non dovresti sostenere costi per completare questo tutorial. Le API Cloud possono essere abilitate dalla console Cloud o dalla riga di comando, a seconda delle tue preferenze.
Dalla console Cloud
Vai alla pagina della libreria di API Manager (per il progetto corretto) in Cloud Console e cerca le API Cloud Datastore e Cloud Pub/Sub utilizzando la barra di ricerca al centro della pagina:

Fai clic sul pulsante Attiva per ogni API separatamente. Potrebbe esserti chiesto di fornire i dati di fatturazione. Ad esempio, questa è la pagina della libreria API Cloud Pub/Sub:

Dalla riga di comando
Sebbene l'abilitazione delle API dalla console sia visivamente informativa, alcuni preferiscono la riga di comando. Esegui il comando gcloud services enable pubsub.googleapis.com datastore.googleapis.com per abilitare entrambe le API contemporaneamente:
$ gcloud services enable pubsub.googleapis.com datastore.googleapis.com Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Potrebbe esserti richiesto di inserire i dati di fatturazione. Se vuoi abilitare altre API Cloud e vuoi sapere quali sono i loro URI, puoi trovarli in fondo alla pagina della libreria di ogni API. Ad esempio, osserva pubsub.googleapis.com come "Nome servizio" nella parte inferiore della pagina Pub/Sub appena sopra.
Una volta completati i passaggi, il tuo progetto potrà accedere alle API. Ora è il momento di aggiornare l'applicazione per utilizzare queste API.
4. Crea risorse Pub/Sub
Riepilogo dell'ordine della sequenza del flusso di lavoro della coda delle attività del modulo 18:
- Il modulo 18 ha utilizzato il file
queue.yamlper creare una coda pull denominatapullq. - L'app aggiunge attività alla coda pull per monitorare i visitatori.
- Le attività vengono alla fine elaborate da un worker, noleggiato per un periodo di tempo finito (un'ora).
- Le attività vengono eseguite per conteggiare i visitatori recenti.
- Le attività vengono eliminate dalla coda al termine.
Replicherai un flusso di lavoro simile con Pub/Sub. La sezione successiva introduce la terminologia di base di Pub/Sub, con tre modi diversi per creare le risorse Pub/Sub necessarie.
Terminologia di App Engine Task Queue (pull) e Cloud Pub/Sub
Il passaggio a Pub/Sub richiede un leggero aggiustamento del vocabolario. Di seguito sono elencate le categorie principali insieme ai termini pertinenti di entrambi i prodotti. Consulta anche la guida alla migrazione, che include confronti simili.
- Struttura dei dati di accodamento:con Task Queue, i dati vengono inseriti nelle code pull; con Pub/Sub, i dati vengono inseriti negli argomenti.
- Unità di dati in coda: le attività pull con la coda di attività sono chiamate messaggi con Pub/Sub.
- Responsabili del trattamento dei dati:con Task Queue, i worker accedono alle attività pull; con Pub/Sub, hai bisogno di abbonamenti/abbonati per ricevere i messaggi
- Estrazione dei dati: leasing di un'attività pull equivale a estrarre un messaggio da un argomento (tramite un abbonamento).
- Pulizia/completamento: l'eliminazione di un'attività Task Queues da una coda pull al termine dell'operazione è analoga al riconoscimento di un messaggio Pub/Sub
Anche se la messa in coda dei prodotti cambia, il flusso di lavoro rimane relativamente simile:
- Anziché una coda pull, l'app utilizza un argomento denominato
pullq. - Anziché aggiungere attività a una coda pull, l'app invia messaggi a un argomento (
pullq). - Anziché un worker che prende in leasing le attività dalla coda pull, un sottoscrittore denominato
workerestrae i messaggi dall'argomentopullq. - L'app elabora i payload dei messaggi, incrementando i conteggi dei visitatori in Datastore.
- Anziché eliminare le attività dalla coda pull, l'app riconosce i messaggi elaborati.
Con Task Queue, la configurazione prevede la creazione della coda pull. Con Pub/Sub, la configurazione richiede la creazione di un argomento e di una sottoscrizione. Nel modulo 18 abbiamo elaborato queue.yaml al di fuori dell'esecuzione dell'app; ora dobbiamo fare lo stesso con Pub/Sub.
Esistono tre opzioni per creare argomenti e sottoscrizioni:
- Dalla console Cloud
- Dalla riga di comando o
- Dal codice (breve script Python)
Scegli una delle opzioni riportate di seguito e segui le istruzioni corrispondenti per creare le risorse Pub/Sub.
Dalla console Cloud
Per creare un argomento dalla console Cloud, segui questi passaggi:
- Vai alla pagina Argomenti Pub/Sub della console Cloud.
- Fai clic su Crea argomento in alto; si apre una nuova finestra di dialogo (vedi immagine sotto)
- Nel campo ID argomento, inserisci
pullq. - Deseleziona tutte le opzioni selezionate e seleziona Chiave di crittografia gestita da Google.
- Fai clic sul pulsante Crea argomento.
Ecco l'aspetto della finestra di dialogo per la creazione di argomenti:

Ora che hai un argomento, devi creare una sottoscrizione per quell'argomento:
- Vai alla pagina Sottoscrizioni Pub/Sub della console Cloud.
- Fai clic su Crea abbonamento in alto (vedi immagine sotto).
- Inserisci
workernel campo ID sottoscrizione. - Scegli
pullqdal menu a discesa Seleziona un argomento Cloud Pub/Sub, annotando il "pathname completo", ad esempioprojects/PROJECT_ID/topics/pullq - Per Tipo di consegna, seleziona Pull.
- Lascia invariate tutte le altre opzioni e fai clic sul pulsante Crea.
Ecco come appare la schermata di creazione dell'abbonamento:

Puoi anche creare una sottoscrizione dalla pagina Argomenti. Questa "scorciatoia" potrebbe esserti utile per associare gli argomenti alle sottoscrizioni. Per saperne di più sulla creazione di abbonamenti, consulta la documentazione.
Dalla riga di comando
Gli utenti Pub/Sub possono creare argomenti e sottoscrizioni con i comandi gcloud pubsub topics create TOPIC_ID e gcloud pubsub subscriptions create SUBSCRIPTION_ID --topic=TOPIC_ID, rispettivamente. L'esecuzione di questi comandi con un TOPIC_ID di pullq e un SUBSCRIPTION_ID di worker produce il seguente output per il progetto PROJECT_ID:
$ gcloud pubsub topics create pullq Created topic [projects/PROJECT_ID/topics/pullq]. $ gcloud pubsub subscriptions create worker --topic=pullq Created subscription [projects/PROJECT_ID/subscriptions/worker].
Consulta anche questa pagina nella documentazione della guida rapida. L'utilizzo della riga di comando potrebbe semplificare i flussi di lavoro in cui vengono creati regolarmente argomenti e abbonamenti e questi comandi possono essere utilizzati negli script shell a questo scopo.
Dal codice (breve script Python)
Un altro modo per automatizzare la creazione di argomenti e sottoscrizioni è utilizzare l'API Pub/Sub nel codice sorgente. Di seguito è riportato il codice per lo script maker.py nella cartella del repository del modulo 19.
from __future__ import print_function
import google.auth
from google.api_core import exceptions
from google.cloud import pubsub
_, PROJECT_ID = google.auth.default()
TOPIC = 'pullq'
SBSCR = 'worker'
ppc_client = pubsub.PublisherClient()
psc_client = pubsub.SubscriberClient()
TOP_PATH = ppc_client.topic_path(PROJECT_ID, TOPIC)
SUB_PATH = psc_client.subscription_path(PROJECT_ID, SBSCR)
def make_top():
try:
top = ppc_client.create_topic(name=TOP_PATH)
print('Created topic %r (%s)' % (TOPIC, top.name))
except exceptions.AlreadyExists:
print('Topic %r already exists at %r' % (TOPIC, TOP_PATH))
def make_sub():
try:
sub = psc_client.create_subscription(name=SUB_PATH, topic=TOP_PATH)
print('Subscription created %r (%s)' % (SBSCR, sub.name))
except exceptions.AlreadyExists:
print('Subscription %r already exists at %r' % (SBSCR, SUB_PATH))
try:
psc_client.close()
except AttributeError: # special Py2 handler for grpcio<1.12.0
pass
make_top()
make_sub()
L'esecuzione di questo script produce l'output previsto (a condizione che non ci siano errori):
$ python3 maker.py Created topic 'pullq' (projects/PROJECT_ID/topics/pullq) Subscription created 'worker' (projects/PROJECT_ID/subscriptions/worker)
La chiamata all'API per creare risorse già esistenti genera un'eccezione google.api_core.exceptions.AlreadyExists generata dalla libreria client, gestita correttamente dallo script:
$ python3 maker.py Topic 'pullq' already exists at 'projects/PROJECT_ID/topics/pullq' Subscription 'worker' already exists at 'projects/PROJECT_ID/subscriptions/worker'
Se non hai mai utilizzato Pub/Sub, consulta il white paper sull'architettura di Pub/Sub per ulteriori informazioni.
5. Aggiorna configurazione
Gli aggiornamenti alla configurazione includono sia la modifica di vari file di configurazione sia la creazione dell'equivalente delle code pull di App Engine, ma all'interno dell'ecosistema Cloud Pub/Sub.
Elimina queue.yaml
Stiamo abbandonando completamente Task Queue, quindi elimina queue.yaml perché Pub/Sub non utilizza questo file. Anziché creare una coda pull, creerai un argomento Pub/Sub (e una sottoscrizione).
requirements.txt
Aggiungi sia google-cloud-ndb che google-cloud-pubsub a requirements.txt per partecipare a flask dal modulo 18. Il modulo 19 aggiornato requirements.txt dovrebbe ora avere questo aspetto:
flask
google-cloud-ndb
google-cloud-pubsub
Questo file requirements.txt non include numeri di versione, il che significa che sono selezionate le versioni più recenti. In caso di incompatibilità, segui la prassi standard di utilizzo dei numeri di versione per bloccare le versioni funzionanti di un'app.
app.yaml
Le modifiche a app.yaml variano a seconda che tu rimanga con Python 2 o esegua l'upgrade a Python 3.
Python 2
L'aggiornamento precedente a requirements.txt aggiunge l'utilizzo delle librerie client di Google Cloud. Questi richiedono un supporto aggiuntivo da parte di App Engine, ovvero un paio di librerie integrate, setuptools e grpcio. L'utilizzo di librerie integrate richiede una sezione libraries in app.yaml e i numeri di versione della libreria o "latest" per la versione più recente disponibile sui server App Engine. Il modulo 18 app.yaml non ha ancora una di queste sezioni:
PRIMA:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
Aggiungi una sezione libraries a app.yaml insieme alle voci per setuptools e grpcio, selezionando le loro ultime versioni. Aggiungi anche una voce segnaposto runtime per Python 3, commentata insieme a una release 3.x attuale, ad esempio 3.10, al momento della stesura di questo articolo. Con queste modifiche, app.yaml ora ha il seguente aspetto:
DOPO:
#runtime: python310
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: setuptools
version: latest
- name: grpcio
version: latest
Python 3
Per gli utenti di Python 3 e app.yaml, si tratta di rimuovere elementi. In questa sezione eliminerai la sezione handlers, le direttive threadsafe e api_version e non creerai una sezione libraries.
I runtime di seconda generazione non forniscono librerie di terze parti integrate, pertanto non è necessaria una sezione libraries in app.yaml. Inoltre, non è più necessario copiare (a volte noto come vendoring o self-bundling) pacchetti di terze parti non integrati. Devi elencare solo le librerie di terze parti utilizzate dalla tua app in requirements.txt.
La sezione handlers in app.yaml serve per specificare i gestori di applicazioni (script) e file statici. Poiché il runtime Python 3 richiede che i framework web eseguano il proprio routing, tutti i gestori di script devono essere modificati in auto. Se la tua app (come quella del modulo 18) non gestisce file statici, tutte le route sarebbero auto, il che le renderebbe irrilevanti. Di conseguenza, non è necessaria nemmeno la sezione handlers, quindi eliminala.
Infine, le direttive threadsafe e api_version non vengono utilizzate in Python 3, quindi eliminale. Il risultato finale è che devi eliminare tutte le sezioni di app.yaml in modo che rimanga solo la direttiva runtime, che specifica una versione moderna di Python 3, ad esempio 3.10. Ecco come si presenta app.yaml prima e dopo questi aggiornamenti:
PRIMA:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
DOPO:
runtime: python310
Per chi non è pronto a eliminare tutto da app.yaml per Python 3, abbiamo fornito un file alternativo app3.yaml nella cartella del repository del modulo 19. Se vuoi utilizzarlo per le implementazioni, assicurati di aggiungere questo nome file alla fine del comando: gcloud app deploy app3.yaml (altrimenti, verrà utilizzato per impostazione predefinita e verrà eseguita l'implementazione dell'app con il file app.yaml Python 2 che hai lasciato invariato).
appengine_config.py
Se esegui l'upgrade a Python 3, non è necessario appengine_config.py, quindi eliminalo. Il motivo per cui non è necessario è che il supporto delle librerie di terze parti richiede solo di specificarle in requirements.txt. Utenti di Python 2, continua a leggere.
Il modulo 18 appengine_config.py contiene il codice appropriato per supportare librerie di terze parti, ad esempio Flask e le librerie client di Cloud appena aggiunte a requirements.txt:
PRIMA:
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
Tuttavia, questo codice da solo non è sufficiente per supportare le librerie integrate appena aggiunte (setuptools, grpcio). Sono necessarie alcune righe aggiuntive, quindi aggiorna appengine_config.py in modo che sia simile a questo:
DOPO:
import pkg_resources
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
# Add libraries to pkg_resources working set to find the distribution.
pkg_resources.working_set.add_entry(PATH)
Per ulteriori dettagli sulle modifiche necessarie per supportare le librerie client Cloud, consulta la documentazione sulla migrazione dei servizi in bundle.
Altri aggiornamenti della configurazione
Se hai una cartella lib, eliminala. Se utilizzi Python 2, ripristina la cartella lib eseguendo questo comando:
pip install -t lib -r requirements.txt # or pip2
Se hai installato sia Python 2 sia Python 3 sul tuo sistema di sviluppo, potresti dover utilizzare pip2 anziché pip.
6. Modificare il codice dell'applicazione
Questa sezione include aggiornamenti al file dell'applicazione principale, main.py, che sostituiscono l'utilizzo delle code pull di App Engine Task Queue con Cloud Pub/Sub. Non sono state apportate modifiche al modello web templates/index.html. Entrambe le app dovrebbero funzionare in modo identico, visualizzando gli stessi dati.
Aggiornare le importazioni e l'inizializzazione
Sono stati apportati diversi aggiornamenti a importazioni e inizializzazione:
- Per le importazioni, sostituisci App Engine NDB e la coda di attività con Cloud NDB e Pub/Sub.
- Rinomina
pullqda un nomeQUEUEa un nomeTOPIC. - Con i pull task, il lavoratore li ha presi in leasing per un'ora, ma con Pub/Sub i timeout vengono misurati in base al messaggio, quindi elimina la costante
HOUR. - Le API Cloud richiedono l'utilizzo di un client API, quindi inizializza quelli per Cloud NDB e Cloud Pub/Sub, con quest'ultimo che fornisce client sia per gli argomenti che per gli abbonamenti.
- Pub/Sub richiede l'ID progetto Cloud, quindi importalo e recuperalo da
google.auth.default(). - Pub/Sub richiede "nomi di percorso completi" per argomenti e sottoscrizioni, quindi creali utilizzando le funzioni di convenienza
*_path().
Di seguito sono riportati le importazioni e l'inizializzazione del modulo 18, seguite da come dovrebbero apparire le sezioni dopo l'implementazione delle modifiche riportate sopra, con la maggior parte del nuovo codice costituito da varie risorse Pub/Sub:
PRIMA:
from flask import Flask, render_template, request
from google.appengine.api import taskqueue
from google.appengine.ext import ndb
HOUR = 3600
LIMIT = 10
TASKS = 1000
QNAME = 'pullq'
QUEUE = taskqueue.Queue(QNAME)
app = Flask(__name__)
DOPO:
from flask import Flask, render_template, request
import google.auth
from google.cloud import ndb, pubsub
LIMIT = 10
TASKS = 1000
TOPIC = 'pullq'
SBSCR = 'worker'
app = Flask(__name__)
ds_client = ndb.Client()
ppc_client = pubsub.PublisherClient()
psc_client = pubsub.SubscriberClient()
_, PROJECT_ID = google.auth.default()
TOP_PATH = ppc_client.topic_path(PROJECT_ID, TOPIC)
SUB_PATH = psc_client.subscription_path(PROJECT_ID, SBSCR)
Visita la pagina Aggiornamenti del modello dati
Il modello di dati Visit non cambia. L'accesso a Datastore richiede l'utilizzo esplicito del gestore del contesto del client API Cloud NDB, ds_client.context(). Nel codice, ciò significa racchiudere le chiamate Datastore sia in store_visit() sia in fetch_visits() all'interno dei blocchi with di Python. Questo aggiornamento è identico a quello trattato nel modulo 2.
La modifica più pertinente per Pub/Sub è la sostituzione dell'accodamento di un'attività pull di Task Queue con la pubblicazione di un messaggio Pub/Sub nell'argomento pullq. Di seguito è riportato il codice prima e dopo aver apportato questi aggiornamenti:
PRIMA:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
def store_visit(remote_addr, user_agent):
'create new Visit in Datastore and queue request to bump visitor count'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
QUEUE.add(taskqueue.Task(payload=remote_addr, method='PULL'))
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
DOPO:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
def store_visit(remote_addr, user_agent):
'create new Visit in Datastore and queue request to bump visitor count'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
ppc_client.publish(TOP_PATH, remote_addr.encode('utf-8'))
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return Visit.query().order(-Visit.timestamp).fetch(limit)
Aggiornamenti del modello di dati VisitorCount
Il modello di dati VisitorCount non cambia e non fa fetch_counts(), tranne per il wrapping della query Datastore all'interno di un blocco with, come illustrato di seguito:
PRIMA:
class VisitorCount(ndb.Model):
visitor = ndb.StringProperty(repeated=False, required=True)
counter = ndb.IntegerProperty()
def fetch_counts(limit):
'get top visitors'
return VisitorCount.query().order(-VisitorCount.counter).fetch(limit)
DOPO:
class VisitorCount(ndb.Model):
visitor = ndb.StringProperty(repeated=False, required=True)
counter = ndb.IntegerProperty()
def fetch_counts(limit):
'get top visitors'
with ds_client.context():
return VisitorCount.query().order(-VisitorCount.counter).fetch(limit)
Aggiorna codice del lavoratore
Il codice del worker viene aggiornato sostituendo NDB con Cloud NDB e Task Queue con Pub/Sub, ma il flusso di lavoro rimane lo stesso.
- Includi le chiamate Datastore nel blocco del gestore di contesto Cloud NDB
with. - La pulizia della coda delle attività prevede l'eliminazione di tutte le attività dalla coda pull. Con Pub/Sub, gli "ID riconoscimento" vengono raccolti in
ackse poi eliminati/riconosciuti alla fine. - Le attività pull di Task Queue vengono affittate in modo simile a come vengono recuperati i messaggi Pub/Sub. Mentre l'eliminazione delle attività pull viene eseguita con gli oggetti attività stessi, i messaggi Pub/Sub vengono eliminati tramite i relativi ID di riconoscimento.
- I payload dei messaggi Pub/Sub richiedono byte (non stringhe Python), quindi è necessaria la codifica e la decodifica UTF-8 quando si pubblicano e si recuperano messaggi da un argomento, rispettivamente.
Sostituisci log_visitors() con il codice aggiornato riportato di seguito, che implementa le modifiche appena descritte:
PRIMA:
@app.route('/log')
def log_visitors():
'worker processes recent visitor counts and updates them in Datastore'
# tally recent visitor counts from queue then delete those tasks
tallies = {}
tasks = QUEUE.lease_tasks(HOUR, TASKS)
for task in tasks:
visitor = task.payload
tallies[visitor] = tallies.get(visitor, 0) + 1
if tasks:
QUEUE.delete_tasks(tasks)
# increment those counts in Datastore and return
for visitor in tallies:
counter = VisitorCount.query(VisitorCount.visitor == visitor).get()
if not counter:
counter = VisitorCount(visitor=visitor, counter=0)
counter.put()
counter.counter += tallies[visitor]
counter.put()
return 'DONE (with %d task[s] logging %d visitor[s])\r\n' % (
len(tasks), len(tallies))
DOPO:
@app.route('/log')
def log_visitors():
'worker processes recent visitor counts and updates them in Datastore'
# tally recent visitor counts from queue then delete those tasks
tallies = {}
acks = set()
rsp = psc_client.pull(subscription=SUB_PATH, max_messages=TASKS)
msgs = rsp.received_messages
for rcvd_msg in msgs:
acks.add(rcvd_msg.ack_id)
visitor = rcvd_msg.message.data.decode('utf-8')
tallies[visitor] = tallies.get(visitor, 0) + 1
if acks:
psc_client.acknowledge(subscription=SUB_PATH, ack_ids=acks)
try:
psc_client.close()
except AttributeError: # special handler for grpcio<1.12.0
pass
# increment those counts in Datastore and return
if tallies:
with ds_client.context():
for visitor in tallies:
counter = VisitorCount.query(VisitorCount.visitor == visitor).get()
if not counter:
counter = VisitorCount(visitor=visitor, counter=0)
counter.put()
counter.counter += tallies[visitor]
counter.put()
return 'DONE (with %d task[s] logging %d visitor[s])\r\n' % (
len(msgs), len(tallies))
Non sono state apportate modifiche al gestore principale dell'applicazione root(). Non sono necessarie modifiche nemmeno nel file modello HTML, templates/index.html, quindi questo conclude tutti gli aggiornamenti necessari. Congratulazioni per aver creato la tua nuova applicazione del modulo 19 utilizzando Cloud Pub/Sub.
7. Riepilogo/Pulizia
Esegui il deployment dell'app per verificare che funzioni come previsto e in qualsiasi output riflesso. Esegui anche il worker per elaborare i conteggi dei visitatori. Dopo la convalida dell'app, esegui i passaggi di pulizia e valuta i passaggi successivi.
Esegui il deployment e verifica l'applicazione
Assicurati di aver già creato l'argomento pullq e la sottoscrizione worker. Se hai completato questa operazione e la tua app di esempio è pronta, esegui il deployment dell'app con gcloud app deploy. L'output dovrebbe essere identico all'app del modulo 18, tranne per il fatto che hai sostituito correttamente l'intero meccanismo di gestione delle code sottostante:

Il frontend web dell'app ora verifica che questa parte dell'applicazione funzioni. Sebbene questa parte dell'app esegua correttamente query e visualizzi i visitatori principali e le visite più recenti, ricorda che l'app registra questa visita e crea un'attività di estrazione per aggiungere questo visitatore al conteggio complessivo. L'attività è ora in coda in attesa di essere elaborata.
Puoi eseguire questa operazione con un servizio di backend App Engine, un job cron, accedendo a /log o inviando una richiesta HTTP dalla riga di comando. Di seguito è riportato un esempio di esecuzione e output della chiamata al codice del worker con curl (sostituisci PROJECT_ID):
$ curl https://PROJECT_ID.appspot.com/log DONE (with 1 task[s] logging 1 visitor[s])
Il conteggio aggiornato verrà visualizzato alla visita successiva del sito web. È tutto.
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:
- I diversi componenti di Cloud Pub/Sub hanno un livello senza costi; determina l'utilizzo complessivo per avere un'idea migliore delle implicazioni sui costi e consulta la pagina dei prezzi per ulteriori dettagli.
- Il servizio App Engine Datastore è fornito da Cloud Datastore (Cloud Firestore in modalità Datastore), che dispone anche di un livello senza costi. Per ulteriori informazioni, consulta la pagina dei prezzi.
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 da App Engine Task Queue (attività push) 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
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 18 (INIZIO) e il Modulo 19 (FINE) sono riportati nella tabella seguente.
Codelab | Python 2 | Python 3 |
(n/a) | ||
Modulo 19 (questo codelab) | (come per Python 2, tranne che devi utilizzare app3.yaml, a meno che tu non abbia aggiornato app.yaml come descritto sopra) |
Riferimenti online
Di seguito sono riportate le risorse pertinenti per questo tutorial:
Coda delle attività App Engine
- Panoramica di App Engine Task Queue
- Panoramica delle code pull di App Engine Task Queue
- App di esempio completa della coda pull di App Engine Task Queue
- Creazione di code pull di Task Queue
- Video di lancio della coda di pull di Google I/O 2011 ( app di esempio Votelator)
queue.yamlriferimentoqueue.yamle Cloud Tasks- Guida alla migrazione delle code in modalità pull a Pub/Sub
Cloud Pub/Sub
- Pagina del prodotto Cloud Pub/Sub
- Utilizzo delle librerie client Pub/Sub
- Esempi di libreria client Python Pub/Sub
- Documentazione della libreria client Python di Pub/Sub
- Crea e gestisci argomenti Pub/Sub
- Linee guida per la denominazione degli argomenti Pub/Sub
- Crea e gestisci le sottoscrizioni Pub/Sub
- App di esempio di App Engine (flessibile) (di cui è possibile eseguire il deployment anche in Standard; Python 3)
- Repository per l'app di esempio riportata sopra
- Sottoscrizioni pull Pub/Sub
- Sottoscrizioni push Pub/Sub
- App di esempio di push Pub/Sub di App Engine (Python 3)
- Repository dell'app di esempio push Pub/Sub di App Engine
- Informazioni sui prezzi di Pub/Sub
- Cloud Tasks o Cloud Pub/Sub? (push vs. pull)
App Engine NDB e Cloud NDB (Datastore)
- Documentazione di App Engine NDB
- Repository NDB di App Engine
- Documenti NDB di Google Cloud
- Repository Google Cloud NDB
- Informazioni sui prezzi di Cloud Datastore
Piattaforma 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
- Lancio della piattaforma App Engine di seconda generazione (2018)
- Confronto tra piattaforme di prima e seconda generazione
- Supporto a lungo termine per i runtime legacy
- Esempi di migrazione della documentazione
- Esempi di migrazione forniti dalla community
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
Video
- Serverless Migration Station
- Serverless Expeditions
- Iscriviti a Google Cloud Tech
- Iscriviti a Google Developers
Licenza
Questo lavoro è concesso in licenza ai sensi di una licenza Creative Commons Attribution 2.0 Generic.