Come utilizzare la coda di attività di App Engine (attività push) nelle app Flask (modulo 7)

1. Panoramica

La serie di codelab Serverless Migration Station (tutorial pratici e self-service) e i video correlati mirano ad aiutare gli sviluppatori Google Cloud serverless a modernizzare le proprie applicazioni guidandoli attraverso una o più migrazioni, principalmente abbandonando i servizi legacy. In questo modo le tue app saranno più portabili e avrai più opzioni e flessibilità, consentendoti di integrare e accedere a una gamma più ampia di prodotti Cloud e di eseguire più facilmente l'upgrade a release delle lingue più recenti. Pur concentrandosi inizialmente sui primi utenti di Cloud, principalmente sviluppatori di App Engine (ambiente standard), questa serie è sufficientemente ampia da includere altre piattaforme serverless come Cloud Functions e Cloud Run, o altrove, se applicabile.

Questo codelab ti insegna a utilizzare le attività di push della coda di attività di App Engine nell'app di esempio del codelab del Modulo 1. Il post del blog e il video del Modulo 7 integrano questo tutorial e forniscono una breve panoramica dei contenuti del tutorial.

In questo modulo, aggiungeremo l'utilizzo delle attività push, quindi migreremo l'utilizzo in Cloud Tasks dal modulo 8 e successivamente a Python 3 e Cloud Datastore nel modulo 9. Gli utenti che utilizzano le code di attività per le attività pull verranno migrati in Cloud Pub/Sub e dovranno fare riferimento ai moduli 18-19.

Imparerai a utilizzare

  • Utilizzare l'API Task Queue/il servizio in bundle di App Engine
  • Aggiungi l'utilizzo di attività di push a un'app NDB di Python 2 Flask App Engine di base

Che cosa ti serve

Sondaggio

Come utilizzerai questo tutorial?

Solo lettura Leggilo e completa gli esercizi

Come valuteresti la tua esperienza con Python?

Principiante Livello intermedio Eccellente

Come giudichi la tua esperienza di utilizzo dei servizi Google Cloud?

Principiante Livello intermedio Eccellente

2. Sfondo

La coda di attività di App Engine supporta sia le attività push che pull. Per migliorare la portabilità delle applicazioni, il team di Google Cloud consiglia di eseguire la migrazione da servizi in bundle legacy, come Task Queue, di altri servizi Cloud autonomi o equivalenti di terze parti.

La migrazione delle attività pull è trattata nei moduli 18-19, mentre i moduli 7-9 sono incentrati sulla migrazione delle attività push. Per eseguire la migrazione dalle attività push della coda di attività di App Engine, aggiungine l'utilizzo all'app NDB e a Flask esistente di App Engine risultante dal codelab del Modulo 1. In tale app, una nuova visualizzazione di pagina registra una nuova visita e mostra le visite più recenti all'utente. Poiché le visite meno recenti non vengono mai mostrate di nuovo e occupano spazio in Datastore, creeremo un'attività push per eliminare automaticamente le visite meno recenti. Nel modulo 8, eseguiremo la migrazione dell'app dalla coda di attività a Cloud Tasks.

Questo tutorial illustra i seguenti passaggi:

  1. Configurazione/pre-lavoro
  2. Aggiorna configurazione
  3. Modifica il codice dell'applicazione

3. Configurazione/pre-lavoro

In questa sezione viene spiegato come:

  1. Configura il progetto Cloud
  2. Ottieni app di esempio di riferimento
  3. (Ri)Esegui il deployment e convalida l'app di riferimento

Questi passaggi assicurano di iniziare con un codice funzionante.

1. Configura il progetto

Se hai completato il codelab del Modulo 1, ti consigliamo di riutilizzare lo stesso progetto (e lo stesso codice). In alternativa, puoi creare un nuovo progetto o riutilizzare un altro progetto esistente. Assicurati che il progetto abbia un account di fatturazione attivo e che App Engine sia abilitato.

2. Ottieni app di esempio di riferimento

Uno dei prerequisiti di questo codelab è avere un'app App Engine del Modulo 1 funzionante: completa il codelab del Modulo 1 (consigliato) oppure copia l'app Modulo 1 dal repository. Sia che utilizzi il tuo o il nostro, il codice del Modulo 1 è il punto in cui "INIZIAMO". Questo codelab ti guiderà in ogni passaggio, concludendo con un codice simile a quello presente nella cartella del repository del modulo 7 "FINISH".

Indipendentemente dall'app del Modulo 1 che utilizzi, la cartella dovrebbe avere l'aspetto seguente, possibilmente con una cartella lib:

$ ls
README.md               main.py                 templates
app.yaml                requirements.txt

3. (Ri)Esegui il deployment dell'app di riferimento

Esegui questi passaggi per (ri)eseguire il deployment dell'app del Modulo 1:

  1. Elimina la cartella lib, se presente, ed esegui: pip install -t lib -r requirements.txt per ricompilare lib. Potresti dover utilizzare il comando pip2 se hai installato sia Python 2 che 3.
  2. Assicurati di aver installato e iniziato lo strumento a riga di comando gcloud e di averne controllato l'utilizzo.
  3. Imposta il tuo progetto Cloud su gcloud config set project PROJECT_ID se non vuoi inserire il valore PROJECT_ID con ogni comando gcloud emesso.
  4. Esegui il deployment dell'app di esempio con gcloud app deploy
  5. Verifica che l'app del Modulo 1 funzioni come previsto senza problemi nella visualizzazione delle visite più recenti (illustrate di seguito)

a7a9d2b80d706a2b.png

4. Aggiorna configurazione

Non sono necessarie modifiche ai file di configurazione standard di App Engine (app.yaml, requirements.txt, appengine_config.py).

5. Modifica i file delle applicazioni

Il file dell'applicazione principale è main.py e tutti gli aggiornamenti in questa sezione riguardano tale file. È presente anche un piccolo aggiornamento al modello web, templates/index.html. Di seguito sono riportate le modifiche da implementare in questa sezione:

  1. Aggiorna importazioni
  2. Aggiungi attività push
  3. Aggiungi gestore di attività
  4. Aggiorna modello web

1. Aggiorna importazioni

Un'importazione di google.appengine.api.taskqueue attiva la funzionalità coda di attività. Sono necessari anche alcuni pacchetti della libreria standard Python:

  • Poiché stiamo aggiungendo un'attività per eliminare le visite meno recenti, l'app dovrà gestire i timestamp, ovvero l'utilizzo di time e datetime.
  • Per registrare informazioni utili relative all'esecuzione dell'attività, abbiamo bisogno di logging.

Aggiungendo tutte queste importazioni, di seguito viene mostrato l'aspetto del codice prima e dopo le modifiche:

PRIMA:

from flask import Flask, render_template, request
from google.appengine.ext import ndb

DOPO:

from datetime import datetime
import logging
import time
from flask import Flask, render_template, request
from google.appengine.api import taskqueue
from google.appengine.ext import ndb

2. Aggiungi attività push (raggruppa i dati per l'attività, aggiungi alla coda una nuova attività)

La documentazione relativa alla coda in modalità push indica: "Per elaborare un'attività, devi aggiungerla a una coda in modalità push. App Engine fornisce una coda push predefinita, denominata default, che è configurata e pronta per l'uso con le impostazioni predefinite. Se vuoi, puoi semplicemente aggiungere tutte le tue attività alla coda predefinita, senza dover creare e configurare altre code." Questo codelab utilizza la coda default per brevità. Per scoprire di più sulla definizione di code in modalità push personalizzate, con caratteristiche uguali o diverse, consulta la documentazione relativa alla creazione di code in modalità push.

L'obiettivo principale di questo codelab è aggiungere un'attività (alla coda di push di default) il cui compito è eliminare da Datastore le visite precedenti che non sono più visualizzate. L'app di riferimento registra ogni visita (richiesta di GET a /) creando una nuova entità Visit, quindi recupera e mostra le visite più recenti. Nessuna delle visite meno recenti verrà mai visualizzata o riutilizzata, quindi l'attività push elimina tutte le visite precedenti alla meno recente visualizzata. Per farlo, il comportamento dell'app deve cambiare leggermente:

  1. Quando esegui una query sulle visite più recenti, anziché restituirle immediatamente, modifica l'app per salvare il timestamp dell'ultima Visit, la meno recente visualizzata. Puoi eliminare tutte le visite precedenti a questa data.
  2. Crea un'attività di push con questo timestamp come payload e indirizzala al gestore di attività, accessibile tramite POST HTTP a /trim. In particolare, usa le utilità Python standard per convertire il timestamp di Datastore e inviarlo (come un numero in virgola mobile) nell'attività, ma anche registrarlo (come stringa) e restituire quella stringa come valore sentinella da visualizzare all'utente.

Tutto questo si svolge in fetch_visits(), ed ecco come si presenta prima e dopo i seguenti aggiornamenti:

PRIMA:

def fetch_visits(limit):
    return (v.to_dict() for v in Visit.query().order(
            -Visit.timestamp).fetch(limit))

DOPO:

def fetch_visits(limit):
    'get most recent visits and add task to delete older visits'
    data = Visit.query().order(-Visit.timestamp).fetch(limit)
    oldest = time.mktime(data[-1].timestamp.timetuple())
    oldest_str = time.ctime(oldest)
    logging.info('Delete entities older than %s' % oldest_str)
    taskqueue.add(url='/trim', params={'oldest': oldest})
    return (v.to_dict() for v in data), oldest_str

3. Aggiungi gestore di attività (codice chiamato quando l'attività viene eseguita)

Sebbene l'eliminazione delle vecchie visite possa essere facilmente eseguita in fetch_visits(), tieni presente che questa funzionalità non ha molto a che fare con l'utente finale. È una funzionalità ausiliaria ed è una buona candidata per elaborare in modo asincrono al di fuori delle richieste di app standard. L'utente finale potrà beneficiare di query più rapide perché ci saranno meno informazioni in Datastore. Crea una nuova funzione trim(), chiamata tramite una richiesta POST della coda di attività a /trim, che esegue queste operazioni:

  1. Estrae la "visita meno recente" payload timestamp
  2. Emette una query Datastore per trovare tutte le entità precedenti a quel timestamp.
  3. Scegli una modalità "solo chiavi" più veloce perché non sono necessari dati utente reali.
  4. Registra il numero di entità da eliminare (incluso zero).
  5. Richiama ndb.delete_multi() per eliminare le entità (saltate in caso contrario).
  6. Restituisce una stringa vuota (insieme a un codice di ritorno HTTP 200 implicito).

Puoi trovare tutto in trim() qui sotto. Aggiungilo a main.py subito dopo il giorno fetch_visits():

@app.route('/trim', methods=['POST'])
def trim():
    '(push) task queue handler to delete oldest visits'
    oldest = request.form.get('oldest', type=float)
    keys = Visit.query(
            Visit.timestamp < datetime.fromtimestamp(oldest)
    ).fetch(keys_only=True)
    nkeys = len(keys)
    if nkeys:
        logging.info('Deleting %d entities: %s' % (
                nkeys, ', '.join(str(k.id()) for k in keys)))
        ndb.delete_multi(keys)
    else:
        logging.info('No entities older than: %s' % time.ctime(oldest))
    return ''   # need to return SOME string w/200

4. Aggiorna modello web

Aggiorna il modello web, templates/index.html, con questo condizionale Jinja2 per visualizzare il timestamp meno recente se esiste questa variabile:

{% if oldest is defined %}
    <b>Deleting visits older than:</b> {{ oldest }}</p>
{% endif %}

Aggiungi questo snippet dopo l'elenco delle visite visualizzato, ma prima di chiudere il corpo in modo che il modello abbia il seguente aspetto:

<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>

<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
    <li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>

{% if oldest is defined %}
    <b>Deleting visits older than:</b> {{ oldest }}</p>
{% endif %}
</body>
</html>

6. Riepilogo/Pulizia

In questa sezione si conclude questo codelab eseguendo il deployment dell'app e verificando che funzioni come previsto e in qualsiasi output riportato. Dopo la convalida dell'app, esegui la pulizia e valuta i passaggi successivi.

Esegui il deployment e verifica l'applicazione

Esegui il deployment dell'app con gcloud app deploy. L'output deve essere identico a quello dell'app del Modulo 1, tranne per una nuova riga in basso che mostra le visite che verranno eliminate:

4aa8a2cb5f527079.png

Complimenti per aver completato il codelab. Il codice ora dovrebbe corrispondere al contenuto della cartella di repository del Modulo 7. Ora è pronto per eseguire la migrazione a Cloud Tasks nel modulo 8.

Esegui la pulizia

Generale

Se per il momento hai finito, ti consigliamo di disabilitare l'app App Engine per evitare di incorrere in fatturazione. Tuttavia, se desideri eseguire altri test o sperimentarli, la piattaforma App Engine ha una quota senza costi, pertanto, se non superi il livello di utilizzo, non ti verrà addebitato alcun costo. Questo riguarda il computing, ma potrebbero essere addebitati costi anche per i servizi App Engine pertinenti, quindi consulta la pagina dei prezzi per ulteriori informazioni. Se la migrazione coinvolge altri servizi Cloud, questi vengono fatturati separatamente. In entrambi i casi, se applicabile, consulta la sezione "Specifici di questo codelab" di seguito.

Per garantire la piena divulgazione, il deployment su una piattaforma di serverless computing di Google Cloud come App Engine comporta costi minori di build e archiviazione. Cloud Build e Cloud Storage hanno una quota senza costi specifica. Lo spazio di archiviazione dell'immagine esaurisce una parte della quota. Tuttavia, potresti risiedere in una regione che non ha un livello senza costi, quindi tieni presente l'utilizzo dello spazio di archiviazione per ridurre al minimo i costi potenziali. "cartelle" specifiche di Cloud Storage da esaminare includono:

  • console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
  • console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
  • I link allo spazio di archiviazione riportati sopra dipendono dalla tua PROJECT_ID e dalla tua *LOC*azione, ad esempio "us" se la tua app è ospitata negli Stati Uniti.

Se invece non intendi continuare con questa applicazione o con altri codelab di migrazione correlati e vuoi eliminare tutto completamente, chiudi il progetto.

Specifico di questo codelab

I servizi elencati di seguito sono esclusivi per questo codelab. Per ulteriori informazioni, fai riferimento alla documentazione di ciascun prodotto:

Passaggi successivi

In questa "migrazione", hai aggiunto l'utilizzo della coda push della coda di attività all'app di esempio del modulo 1, aggiungendo il supporto per il monitoraggio dei visitatori, ottenendo così l'app di esempio del modulo 7. Nella prossima migrazione imparerai a eseguire l'upgrade dalle attività push di App Engine a Cloud Tasks, se necessario. A partire dall'autunno 2021, gli utenti non devono più eseguire la migrazione a Cloud Tasks quando eseguono l'upgrade a Python 3. Scopri di più nella prossima sezione.

Se vuoi passare a Cloud Tasks, il codelab del Modulo 8 è il prossimo. Oltre a questo, ci sono ulteriori migrazioni da considerare, come Cloud Datastore, Cloud Memorystore, Cloud Storage o Cloud Pub/Sub (code pull). Esistono anche migrazioni tra prodotti a Cloud Run e Cloud Functions. È possibile accedere a tutti i contenuti di Serverless Migration Station (codelab, video, codice sorgente [se disponibile]) nel relativo repository open source.

7. Migrazione a Python 3

Nell'autunno 2021, il team di App Engine ha esteso il supporto di molti dei servizi in bundle ai runtime di 2a generazione (originariamente disponibili solo nei runtime di 1a generazione), il che significa che non devi più eseguire la migrazione dai servizi in bundle come la coda delle attività di App Engine a Cloud autonomo o equivalenti di terze parti come Cloud Tasks quando trasferisci la tua app in Python 3. In altre parole, puoi continuare a utilizzare la coda di attività nelle app App Engine in Python 3, purché adatta il codice per accedere ai servizi in bundle dai runtime di nuova generazione.

Per ulteriori informazioni su come eseguire la migrazione a Python 3 dell'utilizzo dei servizi in bundle, consulta il codelab del Modulo 17 e il video corrispondente. Sebbene l'argomento non rientri nell'ambito del Modulo 7, di seguito trovi il link alle versioni Python 3 delle app del Modulo 1 e 7, portate in Python 3 e che utilizzano ancora l'NDB e la coda di attività di App Engine.

8. Risorse aggiuntive

Di seguito sono elencate le risorse aggiuntive per gli sviluppatori che esplorano ulteriormente questo modulo di migrazione o i prodotti correlati, nonché i prodotti correlati. tra cui posizioni in cui fornire feedback su questi contenuti, link al codice e vari documenti che potrebbero esserti utili.

Problemi/feedback del codelab

Se riscontri problemi con questo codelab, cercali prima di procedere con l'invio. Link per eseguire ricerche e creare nuovi problemi:

Risorse di migrazione

I link alle cartelle repository per il modulo 2 (START) e il modulo 7 (FINISH) sono disponibili nella tabella seguente.

Codelab

Python 2

Python 3

Module 1

codice

code (non presente in questo tutorial)

Modulo 7 (questo codelab)

codice

code (non presente in questo tutorial)

Risorse online

Di seguito sono riportate alcune risorse online che potrebbero essere pertinenti per questa esercitazione:

Coda di attività App Engine

Piattaforma App Engine

Altre informazioni sul cloud

Video

Licenza

Questo lavoro è concesso in licenza ai sensi di una licenza Creative Commons Attribution 2.0 Generic.