Modulo 11: Migrazione da Google App Engine a Cloud Functions

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

In alcuni casi non disponi di un'"intera app" per richiedere le risorse di App Engine o Cloud Run. Se il codice è costituito solo da un microservizio o da una funzione semplice, è probabile che Cloud Functions sia la soluzione migliore. Questo codelab ti insegna come eseguire la migrazione di app semplici di App Engine (o suddividere app più grandi in più microservizi) ed eseguirne il deployment su Cloud Functions, un'altra piattaforma serverless creata appositamente per casi d'uso come questo.

Imparerai a utilizzare

  • Utilizzo di Cloud Shell
  • Abilita l'API Google Cloud Translation
  • Autentica le richieste API
  • Converti una piccola app di App Engine da eseguire su Cloud Functions
  • Esegui il deployment del codice in Cloud Functions

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

I sistemi PaaS come Google App Engine e Cloud Functions offrono molte comodità agli utenti. Queste piattaforme serverless consentono al team tecnico di concentrarsi sulla creazione di soluzioni aziendali anziché dedicare tempo a indagare sulle piattaforme da utilizzare e a determinare la quantità di hardware necessaria. Le applicazioni possono fare lo scale up automatico in base alle esigenze e lo scale down a zero con la fatturazione pay-per-use per controllare i costi e consentono l'utilizzo di una varietà di linguaggi di sviluppo comuni odierni.

Tuttavia, sebbene lo sviluppo di applicazioni web full stack o i backend complessi per le app mobile siano ideali per App Engine, spesso gli sviluppatori cercano principalmente di inserire alcune funzionalità online, ad esempio l'aggiornamento di un feed di notizie o il recupero dell'ultimo punteggio della partita di playoff della squadra di casa. Sebbene la logica di programmazione esista per entrambi gli scenari, nessuno dei due sembra essere "applicazioni" complete che richiedono la potenza di App Engine. È qui che entra in gioco Cloud Functions.

Cloud Functions serve a eseguire il deployment della piccola porzione di codice che:

  • Non fa parte di un'intera applicazione
  • Non è necessaria in un intero stack di sviluppo
  • Si trovi in un backend di un'applicazione o di un'unica app mobile incentrato su un aspetto

Puoi anche utilizzare Cloud Functions per suddividere un'applicazione monolitica di grandi dimensioni in più microservizi, ognuno utilizzando un database comune condiviso come Cloud Firestore o Cloud SQL. Se vuoi che la tua funzione o il tuo microservizio sia containerizzato ed eseguito in modo serverless su Cloud Run, puoi farlo.

La nostra app di esempio di App Engine, inclusa in quasi tutti i tutorial sulla migrazione, è una breve app con funzionalità di base che funzionano altrettanto bene in Cloud Functions. In questo tutorial imparerai a modificare l'app per l'esecuzione su Cloud Functions. Dal punto di vista di App Engine, poiché le funzioni sono più semplici di intere app, l'esperienza iniziale dovrebbe essere più semplice (e veloce) e meno "overhead" in generale. Questa migrazione prevede i seguenti passaggi:

  • Configurazione/pre-lavoro
  • Rimuovi i file di configurazione
  • Modifica i file delle applicazioni

3. Configurazione/pre-lavoro

Questo codelab inizia con la versione Python 3 dell'app di esempio Cloud NDB App Engine del Modulo 2 perché Cloud Functions non supporta Python 2. Per prima cosa, configuriamo il progetto, recuperiamo il codice, quindi eseguiamo il deployment dell'app di base per confermare che stiamo iniziando a lavorare con il codice.

1. Configura il progetto

Se hai completato il codelab Modulo 2 (e lo hai trasferito a Python 3), 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 con il servizio App Engine abilitato.

2. Ottieni app di esempio di riferimento

Uno dei prerequisiti di questo codelab è avere un'app di esempio del Modulo 2 funzionante. Se non ne hai uno, completa uno dei tutorial di cui trovi il link qui sopra prima di proseguire. Altrimenti, se ne hai già familiarità, puoi iniziare recuperando il codice del Modulo 2 riportato di seguito.

Che tu usi il tuo o il nostro, il codice Python 3 del Modulo 2 è quello che iniziamo. Questo codelab del Modulo 11 illustra ogni passaggio, concludendo con un codice simile a quello presente nella cartella di repository del Modulo 11 (FINISH).

La directory dei file Python 3 del Modulo 2 AVVIO (tuoi o nostri) dovrebbe avere questo aspetto:

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

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

I passaggi preliminari rimanenti da eseguire ora:

  1. Acquisisci familiarità con lo strumento a riga di comando gcloud
  2. Esegui di nuovo il deployment dell'app di esempio con gcloud app deploy
  3. Verifica che l'app venga eseguita su App Engine senza problemi

Una volta eseguiti questi passaggi, puoi convertirla in una funzione Cloud Functions.

4. Rimuovi i file di configurazione

Il file app.yaml è un artefatto di App Engine non utilizzato con Cloud Functions, quindi eliminalo ora. Se non lo fai o dimentichi di farlo, non c'è nulla di male in quanto Cloud Functions non lo usa. Questa è l'unica modifica alla configurazione, in quanto requirements.txt rimane identico a quello del Modulo 2.

Se stai trasferendo anche un'app App Engine di Python 2 a Python 3, elimina appengine_config.py e la cartella lib, se ne hai una. Sono artefatti di App Engine non utilizzati nel runtime di Python 3.

5. Modifica i file delle applicazioni

Esiste un solo file dell'applicazione, main.py, quindi tutte le modifiche necessarie per passare a Cloud Functions vengono eseguite in questo file.

Importazioni

Poiché lavoriamo solo con le funzioni, non è necessario un framework per applicazioni web. Tuttavia, per praticità, quando vengono chiamate le funzioni Cloud Functions basate su Python, viene passato automaticamente un oggetto di richiesta per il codice da utilizzare all'occorrenza. Il team di Cloud Functions lo ha selezionato come oggetto richiesta Flask passato alla tua funzione.

Poiché i framework web non fanno parte del panorama di Cloud Functions, non è possibile eseguire importazioni da Flask a meno che la tua app non utilizzi altre funzionalità di Flask. Questo è davvero il nostro caso, poiché il rendering del modello viene ancora eseguito dopo la conversione in una funzione, il che significa che è ancora necessaria una chiamata a flask.render_template() e, di conseguenza, l'importazione da Flask. Poiché non esiste alcun framework web, non è necessario creare un'istanza per un'app Flask, quindi elimina app = Flask(__name__). Prima e dopo l'applicazione delle modifiche, il tuo codice sarà simile al seguente:

PRIMA:

from flask import Flask, render_template, request
from google.cloud import ndb

app = Flask(__name__)
ds_client = ndb.Client()

DOPO:

from flask import render_template
from google.cloud import ndb

ds_client = ndb.Client()

Se dipendi dall'oggetto app (app) o da qualsiasi altra infrastruttura del framework web, devi risolvere tutte queste dipendenze, trovare soluzioni alternative adeguate, rimuoverne completamente l'utilizzo o trovare proxy. Solo a questo punto puoi convertire il codice in una funzione Cloud Functions. In caso contrario, sarà preferibile rimanere su App Engine o containerizzare l'app per Cloud Run.

Aggiorna la firma della funzione del gestore principale

Le modifiche richieste nella firma della funzione sono le seguenti:

  1. Flask non viene più utilizzato dopo la conversione dell'app in una funzione Cloud Functions, quindi rimuovi i decoratori delle route.
  2. Cloud Functions passa automaticamente all'oggetto Flask Request come parametro, quindi crea una variabile apposita. Nella nostra app di esempio, lo chiameremo request.
  3. Le funzioni Cloud Functions di cui è stato eseguito il deployment devono essere denominate. Il nostro gestore principale è stato nominato correttamente root() in App Engine per descriverlo (il gestore delle applicazioni radice). Come funzione Cloud Functions, non ha più senso utilizzare questo nome. Eseguiremo invece il deployment della funzione Cloud Functions con il nome visitme, quindi usalo anche come nome della funzione Python. Allo stesso modo, nei moduli 4 e 5 abbiamo denominato anche il servizio Cloud Run visitme.

Ecco i prima e dopo questi aggiornamenti:

PRIMA:

@app.route('/')
def root():
    'main application (GET) handler'
    store_visit(request.remote_addr, request.user_agent)
    visits = fetch_visits(10)
    return render_template('index.html', visits=visits)

DOPO:

def visitme(request):
    'main application (GET) handler'
    store_visit(request.remote_addr, request.user_agent)
    visits = fetch_visits(10)
    return render_template('index.html', visits=visits)

Con questo sono terminati tutti gli aggiornamenti necessari. Tieni presente che le modifiche apportate hanno interessato solo l'"infrastruttura" dell'applicazione le API nel tuo codice. Non sono necessarie modifiche al codice dell'applicazione principale e nessuna delle funzionalità dell'app è stata alterata. Ecco una rappresentazione grafica delle modifiche apportate per illustrare questo punto:

668f30e3865b27a9.png

Sviluppo e test locali

Mentre App Engine dispone del server di sviluppo locale dev_appserver.py, Cloud Functions ha il suo framework delle funzioni. Con questo framework, puoi sviluppare ed eseguire test in locale. Puoi eseguire il deployment del codice su Cloud Functions, ma anche su altre piattaforme di computing come Compute Engine, Cloud Run o anche sistemi cloud on-prem o ibridi che supportano Knative. Di seguito sono riportati link aggiuntivi al framework di Functions.

6. Creazione e deployment

Il deployment in Cloud Functions è leggermente diverso da App Engine. Poiché non viene utilizzato alcun file di configurazione al di fuori di requirements.txt, è necessario specificare ulteriori informazioni sul codice nella riga di comando. Esegui il deployment della nuova funzione Cloud Functions attivata da HTTP in esecuzione in Python 3.10 con questo comando:

$ gcloud functions deploy visitme --runtime python310 --trigger-http --allow-unauthenticated

È previsto un output simile al seguente:

Deploying function (may take a while - up to 2 minutes)...⠛
For Cloud Build Logs, visit: https://console.cloud.google.com/cloud-build/builds;region=REGION/f5f6fc81-1bb3-4cdb-8bfe?project=PROJECT_ID
Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 256
buildId: f5f6fc81-1bb3-4cdb-8bfe
buildName: projects/PROJECT_ID/locations/REGION/builds/f5f6fc81-1bb3-4cdb-8bfe
dockerRegistry: CONTAINER_REGISTRY
entryPoint: visitme
httpsTrigger:
  securityLevel: SECURE_OPTIONAL
  url: https://REGION-PROJECT_ID.cloudfunctions.net/visitme
ingressSettings: ALLOW_ALL
labels:
  deployment-tool: cli-gcloud
name: projects/PROJECT_ID/locations/REGION/functions/visitme
runtime: python310
serviceAccountEmail: PROJECT_ID@appspot.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/uploads-853031211983.REGION.cloudfunctions.appspot.com/8c923758-cee8-47ce-8e97-5720a5301c34.zip
status: ACTIVE
timeout: 60s
updateTime: '2022-05-16T18:28:06.153Z'
versionId: '8'

Una volta eseguito il deployment della funzione, utilizza l'URL dell'output del deployment e visita l'app. L'URL è nel formato: REGION-PROJECT_ID.cloudfunctions.net/visitme. L'output dovrebbe essere identico a quando ne hai eseguito il deployment in App Engine in precedenza:

2732ae9218f011a2.png

Come per la maggior parte degli altri codelab e video della serie, la funzionalità di base dell'app non cambia. Lo scopo è applicare una tecnica di modernizzazione e fare in modo che l'app funzioni esattamente come prima ma supportata da un'infrastruttura più recente, ad esempio eseguendo la migrazione da un servizio legacy precedente di App Engine al prodotto autonomo Cloud sostitutivo oppure, come nel caso di questo tutorial, spostando un'app su un'altra piattaforma serverless Google Cloud.

7. Riepilogo/Pulizia

Complimenti per aver convertito questa piccola app di App Engine in una funzione Cloud Functions. Un altro caso d'uso appropriato è la suddivisione di una grande app monolitica di App Engine in una serie di microservizi, ciascuno come funzione Cloud Functions. Si tratta di una tecnica di sviluppo più moderna che si traduce in una maggiore "plug-and-play" (uno stile "Stack JAM"). Consente la combinazione, la corrispondenza e il riutilizzo del codice, che sono due obiettivi, ma un altro vantaggio è che questi microservizi continueranno a essere sottoposti a debug nel tempo, il che significa codice stabile e costi di manutenzione inferiori nel complesso.

Esegui la pulizia

Dopo aver completato questo codelab, puoi disabilitare l'app App Engine del modulo 2 (temporaneamente o definitivamente) per evitare addebiti. La piattaforma App Engine ha una quota senza costi, quindi non ti verrà addebitato alcun costo finché rimani entro il suo livello di utilizzo. Lo stesso vale per Datastore; per ulteriori dettagli, consulta la pagina dei prezzi di Cloud Datastore.

Il deployment su piattaforme come App Engine e Cloud Functions comporta costi minori di creazione e archiviazione. In alcune regioni, Cloud Build ha la propria quota senza costi, così come Cloud Storage. Le build consumano parte di quella quota. Tieni presente l'utilizzo dello spazio di archiviazione per ridurre al minimo i costi potenziali, soprattutto se la tua regione non ha un livello senza costi di questo tipo.

Purtroppo Cloud Functions non ha un'opzione "disable" funzionalità. Esegui il backup del codice ed elimina la funzione. Puoi sempre rieseguire il deployment con lo stesso nome in un secondo momento. Tuttavia, se non intendi continuare con altri codelab di migrazione e vuoi eliminare completamente tutto, chiudi i progetti Cloud.

Passaggi successivi

Oltre a questo tutorial, altri moduli di migrazione da esaminare includono la containerizzazione dell'app App Engine per Cloud Run. Ecco i link ai codelab del Modulo 4 e 5:

  • Modulo 4: Esegui la migrazione a Cloud Run con Docker
  • Containerizza la tua app per eseguirla su Cloud Run con Docker
  • Questa migrazione ti consente di rimanere su Python 2.
  • Modulo 5: Esegui la migrazione a Cloud Run con Cloud Buildpacks
  • Containerizza la tua app per eseguirla su Cloud Run con Cloud Buildpacks
  • Non devi conoscere Docker, container o Dockerfile.
  • Richiede che l'app abbia già eseguito la migrazione a Python 3 (Buildpacks non supporta Python 2)

Molti degli altri moduli sono incentrati su come mostrare agli sviluppatori come eseguire la migrazione dai servizi in bundle di App Engine alle sostituzioni Cloud autonomo:

  • Modulo 2: migrazione da App Engine ndb a Cloud NDB
  • Moduli 7-9: migrazione dalle attività di push della coda di attività di App Engine a Cloud Tasks
  • Moduli 12-13: migrazione da App Engine Memcache a Cloud Memorystore
  • Moduli 15-16: migrazione dal Blobstore di App Engine a Cloud Storage
  • Moduli 18-19: migrazione dalla coda di attività di App Engine (attività pull) a Cloud Pub/Sub

Se la containerizzazione è diventata parte del flusso di lavoro per lo sviluppo delle applicazioni, in particolare se è costituita da una pipeline CI/CD (integrazione continua/distribuzione continua o deployment), valuta la possibilità di eseguire la migrazione a Cloud Run anziché a Cloud Functions. Vedi il Modulo 4 per containerizzare la tua app con Docker oppure il Modulo 5 per farlo senza container, conoscenze di Docker o Dockerfile. Sia che tu stia prendendo in considerazione Cloud Functions o Cloud Run, 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 successivo, sarà possibile accedere a tutti i contenuti di Serverless Migration Station (codelab, video, codice sorgente [se disponibile]) nel relativo repository open source. L'elemento README del repository fornisce anche indicazioni sulle migrazioni da prendere in considerazione e su eventuali "ordine" pertinenti dei Moduli di migrazione.

8. Risorse aggiuntive

Problemi/feedback dei codelab per i moduli di migrazione di App Engine

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 8 (START) e il modulo 9 (FINISH) sono disponibili nella tabella seguente. Sono inoltre accessibili dal repository per tutte le migrazioni del codelab di App Engine che puoi clonare o scaricare un file ZIP.

Codelab

Python 3

Modulo 2

codice

Modulo 11

codice

Risorse online

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

App Engine

Cloud Functions

Altre informazioni sul cloud

Video

Licenza

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